import sqlite3
import os

DB_VERSION = 1


class McGetDB:

    def __init_db(self):
        with self.db as db:
            db.execute('''
                CREATE TABLE IF NOT EXISTS mods (
                    slug TEXT PRIMARY KEY NOT NULL,
                    proj_name TEXT NOT NULL,
                    filename TEXT NOT NULL,
                    version TEXT NOT NULL,
                    hash TEXT NOT NULL
                );''')
            db.execute('''
                CREATE TABLE IF NOT EXISTS resourcepacks (
                    slug TEXT PRIMARY KEY NOT NULL,
                    proj_name TEXT NOT NULL,
                    filename TEXT NOT NULL,
                    version TEXT NOT NULL,
                    hash TEXT NOT NULL
                );''')
            db.execute('''
                CREATE TABLE IF NOT EXISTS shaderpacks (
                    slug TEXT PRIMARY KEY NOT NULL,
                    proj_name TEXT NOT NULL,
                    filename TEXT NOT NULL,
                    version TEXT NOT NULL,
                    hash TEXT NOT NULL
                );''')
            db.execute('''
                CREATE TABLE IF NOT EXISTS modpacks (
                    slug TEXT PRIMARY KEY NOT NULL,
                    proj_name TEXT NOT NULL,
                    filename TEXT NOT NULL,
                    version TEXT NOT NULL,
                    hash TEXT NOT NULL
                );''')
            db.execute('''
                CREATE TABLE IF NOT EXISTS properties (
                    db_version TEXT PRIMARY KEY NOT NULL,
                    version TEXT NOT NULL,
                    modloader TEXT,
                    dir_hierarchy TEXT
                );''')

    def __init__(self, mc_path):
        self.db_path = os.path.join(mc_path, "mcget.db")
        self.db = sqlite3.connect(self.db_path)
        self.__init_db()

        self.add_mod = self.__db_insert("mods")
        self.add_resourcepack = self.__db_insert("resourcepacks")
        self.add_shader = self.__db_insert("shaderpacks")
        self.add_modpack = self.__db_insert("modpacks")

        self.select_mod = self.__db_select_by_col("mods", "slug")
        self.select_resourcepack = self.__db_select_by_col("resourcepacks", "slug")
        self.select_shader = self.__db_select_by_col("shaderpacks", "slug")
        self.select_modpack = self.__db_select_by_col("modpacks", "slug")

        self.remove_mod = self.__db_remove_by_col("mods", "slug")
        self.remove_resourcepack = self.__db_remove_by_col("resourcepacks", "slug")
        self.remove_shader = self.__db_remove_by_col("shaderpacks", "slug")
        self.remove_modpack = self.__db_remove_by_col("modpacks", "slug")

    def get_properties(self):
        properties = None
        with self.db as db:
            properties = db.execute('''
                SELECT * FROM properties;
            ''').fetchone()
        return properties

    def set_properties(self, mc_ver, modloader="NULL", dir_hierarhy="default"):
        with self.db as db:
            db.execute('''
            DELETE FROM properties;
            ''')
            db.execute('''
            INSERT INTO properties VALUES (?, ?, ?, ?)
            ''', (DB_VERSION, mc_ver, modloader, dir_hierarhy))

    def __db_insert(self, table):
        def insertion_func(**kargs):
            keys = []
            values = []
            for key, value in kargs.items():
                keys.append(key)
                values.append(value)
            with self.db as db:
                db.execute(f'''
                INSERT INTO {table} ({', '.join([key for key in keys])}) VALUES ({', '.join(['?' for _ in values])})
                ''', values)
        return insertion_func

    def __db_select_by_col(self, table, col):
        def selection_func(col_value):
            with self.db as db:
                res = db.execute(f'SELECT * FROM {table} WHERE {col} = "{col_value}"')
            return res.fetchall()
        return selection_func

    def __db_remove_by_col(self, table, col):
        def removal_func(col_value):
            with self.db as db:
                db.execute(f'DELETE FROM {table} WHERE {col} = "{col_value}"')
        return removal_func

    def update_mod(self):
        pass