package me.km.databank;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import me.hammerle.snuviscript.code.ISnuviLogger;
import me.km.scheduler.SnuviScheduler;

public class DataBank {
    private final ISnuviLogger logger;
    private Connection c = null;
    private final String user;
    private final String password;

    private final HashMap<String, PreparedStatement> statements = new HashMap<>();

    public DataBank(ISnuviLogger logger, String user, String password) {
        this.logger = logger;
        this.user = user;
        this.password = password;
    }

    public boolean openDataBankConnection() {
        try {
            // The newInstance() call is a work around for some broken Java implementations
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            c = DriverManager.getConnection("jdbc:mysql://localhost/minecraft?useSSL=false", user, password);
            logger.print("connection to databank etablished");
            return true;
        } catch(ClassNotFoundException | IllegalAccessException | InstantiationException | SQLException ex) {
            logger.print(ex);
            return false;
        }
    }

    public void closeDataBankConnection() {
        try {
            if(c != null) {
                c.close();
                statements.values().forEach(stmt -> {
                    try {
                        stmt.close();
                    } catch(SQLException ex) {
                    }
                });
            }
            logger.print("connection to databank was closed");
        } catch(SQLException ex) {
            logger.print(ex);
        }
    }

    public boolean isDummyDatabank() {
        return c == null;
    }

    public PreparedStatement prepareStatement(String query) {
        try {
            PreparedStatement ps = c.prepareStatement(query);
            PreparedStatement old = statements.put(query, ps);
            if(old != null) {
                old.close();
            }
            return ps;
        } catch(SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public PreparedStatement prepareUnsafeStatement(String query) throws SQLException {
        return c.prepareStatement(query);
    }

    public boolean execute(String query) {
        if(c == null) {
            return false;
        }
        try(java.sql.Statement stmt = c.createStatement()) {
            stmt.executeUpdate(query);
            return true;
        } catch(SQLException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    public void startReconnecting(SnuviScheduler scheduler) {
        if(c == null) {
            return;
        }
        scheduler.scheduleRepeatingTask(() -> {
            try(java.sql.Statement stmt = c.createStatement()) {
                // pointless query just for reconnecting
                stmt.executeUpdate("SHOW TABLES IN minecraft");
            } catch(SQLException ex) {
                logger.print("reconnect was done");
            }
        }, 100, 12000); // doing this every 10 minutes
    }
}
