package net.cobem.grizzly.storage;


import net.cobem.grizzly.Grizzly;
import net.cobem.grizzly.utils.Configuration;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;

public class DatabaseHandler {
    private DatabasePool Pool;
    private DatabaseResultMonitor ResultMonitor;
    private Thread Monitor;
    public int QueryCount;

    public boolean connect(Configuration Config) {
        try {
            Class.forName("com.mysql.jdbc.Driver");

            Pool = new DatabasePool(Config);
            ResultMonitor = new DatabaseResultMonitor();

            Monitor = new Thread(ResultMonitor);
            Monitor.setPriority(Thread.MIN_PRIORITY);
            Monitor.start();

            QueryCount = 0;
            return true;
        } catch (Exception SQL) {
            Grizzly.write(SQL.getMessage());
            return false;
        }
    }

    public boolean execute(String SQL) {
        //Grizzly.WriteOut("Trying to run: " + SQL);

        QueryCount++;

        try (Connection DBConnection = this.Pool.GrabConnection()) {
            DBConnection.createStatement().execute(SQL);
        } catch (Exception ex) {
            Grizzly.write(ex.getMessage());
            return false;
        }

        return true;
    }

    public DatabaseResult query(String SQL) {
        QueryCount++;

        try (Connection DBConnection = this.Pool.GrabConnection()) {
            DatabaseResult Res = new DatabaseResult(SQL, DBConnection, DBConnection.createStatement().executeQuery(SQL));
            ResultMonitor.AddTo(Res);

            return Res;
        } catch (Exception ex) {
            Grizzly.write(ex.getMessage());
            return null;
        }
    }

    public DatabaseResult preparedQuery(String SQL, List<String> args) {
        QueryCount++;

        int Key = 1;
        try (Connection DBConnection = this.Pool.GrabConnection()) {

            PreparedStatement statement = DBConnection.prepareStatement(SQL);

            for(String obj : args) {
                if (Grizzly.tryParse(obj)) {
                    statement.setInt(Key, Integer.parseInt(obj));
                } else {
                    statement.setString(Key, obj);
                }

                Key++;
            }

            DatabaseResult Res = new DatabaseResult(SQL, DBConnection, statement.executeQuery());

            ResultMonitor.AddTo(Res);

            return Res;
        } catch (Exception ex) {
            Grizzly.write(ex.getMessage());
            return null;
        }
    }

    public int getLastEntry(String Table, String WhereClause) {
        if (WhereClause != null) {
            //Grizzly.write("SELECT id FROM " + Table + " WHERE " + WhereClause + " ORDER BY id DESC LIMIT 1");

            DatabaseResult Entry = this.query("SELECT id FROM " + Table + " WHERE " + WhereClause + " ORDER BY id DESC LIMIT 1");

            return Entry.getInt();
        }

        DatabaseResult Entry = this.query("SELECT id FROM " + Table + " ORDER BY id DESC LIMIT 1");

        return Entry.getInt();
    }

    public DatabasePool getPool() {
        return Pool;
    }

    public void clearCount() {
        QueryCount = 0;
    }
}
