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;
        }
    }
}