using MySqlConnector;
using SharpChat.Configuration;

namespace SharpChat.EventStorage;

public partial class MariaDBEventStorage {
    public static string BuildConnString(Configuration.Config config) {
        return BuildConnString(
            config.ReadValue("host", "localhost"),
            config.ReadValue("user", string.Empty),
            config.ReadValue("pass", string.Empty),
            config.ReadValue("db", "sharpchat")
        );
    }

    public static string BuildConnString(string? host, string? username, string? password, string? database) {
        return new MySqlConnectionStringBuilder {
            Server = host,
            UserID = username,
            Password = password,
            Database = database,
            OldGuids = false,
            TreatTinyAsBoolean = false,
            CharacterSet = "utf8mb4",
            SslMode = MySqlSslMode.None,
            ForceSynchronous = true,
            ConnectionTimeout = 5,
            DefaultCommandTimeout = 900, // fuck it, 15 minutes
        }.ToString();
    }

    private MySqlConnection GetConnection() {
        MySqlConnection conn = new(ConnectionString);
        conn.Open();
        return conn;
    }

    private int RunCommand(string command, params MySqlParameter[] parameters) {
        try {
            using MySqlConnection conn = GetConnection();
            using MySqlCommand cmd = conn.CreateCommand();
            if(parameters?.Length > 0)
                cmd.Parameters.AddRange(parameters);
            cmd.CommandText = command;
            return cmd.ExecuteNonQuery();
        } catch(MySqlException ex) {
            Logger.Write(ex);
        }

        return 0;
    }

    private MySqlDataReader? RunQuery(string command, params MySqlParameter[] parameters) {
        try {
            MySqlConnection conn = GetConnection();
            MySqlCommand cmd = conn.CreateCommand();
            if(parameters?.Length > 0)
                cmd.Parameters.AddRange(parameters);
            cmd.CommandText = command;
            return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
        } catch(MySqlException ex) {
            Logger.Write(ex);
        }

        return null;
    }

    private T RunQueryValue<T>(string command, params MySqlParameter[] parameters)
        where T : struct {
        try {
            using MySqlConnection conn = GetConnection();
            using MySqlCommand cmd = conn.CreateCommand();
            if(parameters?.Length > 0)
                cmd.Parameters.AddRange(parameters);
            cmd.CommandText = command;
            cmd.Prepare();

            object? raw = cmd.ExecuteScalar();
            if(raw is T value)
                return value;
        } catch(MySqlException ex) {
            Logger.Write(ex);
        }

        return default;
    }
}