from .model import Model, ModelFunc
import time
import os
import platform
import datetime
import imp
import sqlite3

version = "0.2.9.1"
testing = False
beta = False
if testing:
    version += "-test"
elif beta:
    version += "-beta"
version_str = f"SQL-Cable Build {version}"
package_url = "url"


class Session:
    def __init__(self, db_path):
        self.db_path = db_path
        self.conn = sqlite3.connect(self.db_path)
        self.c = self.conn.cursor()

    def add(self, obj):
        obj.add_query(self.c)

    def save(self):
        self.conn.commit()

    def select(self, selectobj):
        return selectobj.execute(self.c)

    def stop(self):
        self.conn.close()


class DB:
    def __init__(self, app=None):
        self.models = []
        if platform.system() == 'Windows':
            self.path_break = '\\'
        else:
            self.path_break = '/'
        if app:
            self.init(app)
        if testing or beta:
            print(f"""WARNING you are running a {'test' if testing else 'beta'} build of SQL-Cable build version: {version}
This build maybe unstable and have bugs or other problems
Please update to the latest full build of SQL-Cable by
typing 'pip install sql-cable' in the cmd""")

    def init(self, app):
        self.app = app
        self.db_path = app.config['DB_PATH']
        self.session = Session(self.db_path)

    def register_model(self, model):
        model.db_path = self.db_path
        model.session = self.session
        model.check_for_changes(model, self.session)
        # print(str(model).split('.')[1].replace("'>", ''))
        model.load_querrys(model)
        self.models.append(model)

    def make_migrations(self, path=None):
        mirgrations = {}
        for model in self.models:
            if model.check_for_changes(model, self.session) != []:
                mirgrations[model.model.name] = model.generate_migrations(model)
        if mirgrations != {}:
            if not os.path.isdir('migrations'):
                os.mkdir('migrations')
                with open(path if path else f"migrations{self.path_break}__init__.py", 'w') as f:
                    pass
            all_files = [f for f in os.listdir('migrations') if os.path.isfile(os.path.join('migrations', f))]
            current_number = 0
            for file in all_files:
                if str(file).split('_')[0] == 'migration':
                    if int(str(file).split('_')[1].split('.')[0]) > current_number:
                        current_number = int(str(file).split('_')[1].split('.')[0])
            file_str = f"# Generated by {version_str} on {datetime.datetime.now()}\nfrom sql_cable.migrations import Migration\n"

            model_names = []

            for migration in mirgrations:
                if mirgrations[migration]:
                    model_name = migration
                    model_names.append(model_name)
                    file_str += mirgrations[migration]

            for model_name in model_names:
                file_str += f"\n\n\nmodels = {model_names}"
            with open(path if path else f"migrations{self.path_break}migration_{current_number + 1}.py", 'w') as f:
                f.write(file_str)
            file_name = f"migration_{current_number + 1}"
            with open(path if path else f"migrations{self.path_break}__init__.py", 'a') as f:
                f.write(f"\nfrom . import {file_name}")
        else:
            print("No migrations to make.")

    def migrate(self, path=None):
        if not os.path.isdir('migrations'):
            print("No dir named migrations could be found.")
        else:
            all_files = [f for f in os.listdir('migrations') if os.path.isfile(os.path.join('migrations', f))]
            current_number = 0
            for file in all_files:
                if str(file).split('_')[0] == 'migration':
                    if int(str(file).split('_')[1].split('.')[0]) > current_number:
                        current_number = int(str(file).split('_')[1].split('.')[0])
            file_name = f"migration_{current_number}"
            migrate_file = __import__(f"migrations")
            _locals = locals()
            exec(f"models = migrate_file.{file_name}.models", globals(), _locals)
            for model in _locals['models']:
                exec(f"model_in = migrate_file.{file_name}.{model}", globals(), _locals)
                _locals['model_in']().run_migration(self.db_path)
