import uuid
import tomlkit

from wurker.settings import conf

from wurker.cli.base import BaseCommand


class ConfigCommand(BaseCommand):
    """Encapsulate config command."""

    def __init__(self, logger=None):
        BaseCommand.__init__(self, logger=logger)

        self.config_file = conf.config_file
        self.config = conf.config


    def get(self, table:str='', key:str=''):
        """Read the config file in and return it."""

        if not table and not key:
            return self.config

        if key and not table:
            raise Exception(f"Invalid 'key' argument '{key}': not allowed without 'table'")

        if table not in self.config:
            raise Exception(f"Invalid 'table' argument '{table}': not found in config file")

        table_cfg = self.config[table]
        if not key:
            return table_cfg

        if key not in table_cfg:
            raise Exception(f"Invalid 'table.key' argument '{table}.{key}': not found in config file")

        return table_cfg[key]


    def set(self, table:str, key:str, value:str):
        """Set a table[key]=value setting in the config file."""

        if table not in self.config:
            raise Exception(f"Invalid 'table' argument '{table}': not found in config file")

        if key not in self.config[table]:
            raise Exception(f"Invalid 'table.key' argument '{table}.{key}': not found in config file")

        # We want to match type when we write to toml
        old_value = self.config[table][key]

        # Cast the new value to the right type to write out
        new_value = value
        if isinstance(old_value, bool):
            if value.lower() not in ['0', 'false', '1', 'true']:
                raise Exception(f"Invalid '{table}.{key}' boolean value '{value}': must be 'true' or 'false'")
            new_value = True if value.lower() in ['1', 'true'] else False

        elif isinstance(old_value, int):
            if not value.isnumeric():
                raise Exception(f"Invalid '{table}.{key}' integer value '{value}': must be numeric")
            new_value = int(value)

        # Now we can read into new tomlkit object, update, and write out
        with open(self.config_file, 'r') as fh:
            toml = tomlkit.load(fh)
            toml[table][key] = new_value

        with open(self.config_file, 'w') as fh:
            tomlkit.dump(toml, fh)


    def reset(self):
        """Generate a default TOML configuration and write it to the config file."""

        # Create a new TOML document
        config = tomlkit.document()

        # Add the [wurker] section
        wurker_table = tomlkit.table()
        wurker_table.add("name", "Wurker")
        wurker_table.add("app_id", "6b018c2b-77b7-40ca-bb82-cc8378252f67")
        wurker_table["app_id"].comment("Must be UUID")
        wurker_table.add("env", "local")
        wurker_table["env"].comment("'local', 'development', or 'production'")
        wurker_table.add("log", "stderr")
        wurker_table["log"].comment("'stdout' or 'syslog'")
        wurker_table.add("loglevel", "debug")
        wurker_table.add("is_queen", True)
        wurker_table.add("debug", True)

        config.add("wurker", wurker_table)

        # Add the [ui] section
        ui_table = tomlkit.table()
        ui_table.add("domain", "")
        ui_table["domain"].comment("Default: localhost")
        ui_table.add("workers", 3)
        ui_table["workers"].comment("Default: 3")

        config.add("ui", ui_table)

        # Add the [local_db] section
        local_db_table = tomlkit.table()
        local_db_table.add("hostname", "")
        local_db_table["hostname"].comment("Default: local sqlite file")
        local_db_table.add("username", "")
        local_db_table["username"].comment("Default: local sqlite file")
        local_db_table.add("password", "")
        local_db_table["password"].comment("Default: local sqlite file")
        local_db_table.add("database", "wurker.db")
        local_db_table["database"].comment("Default: local sqlite file 'wurker.db'")
        local_db_table.add("dbdriver", "sqlite")
        local_db_table["dbdriver"].comment("Default: 'sqlite'")
        local_db_table.add("port", 0)

        config.add("local_db", local_db_table)

        # Add the [remote_db] section
        remote_db_table = tomlkit.table()
        remote_db_table.add("hostname", "")
        remote_db_table["hostname"].comment("Default: local sqlite file")
        remote_db_table.add("username", "")
        remote_db_table["username"].comment("Default: local sqlite file")
        remote_db_table.add("password", "")
        remote_db_table["password"].comment("Default: local sqlite file")
        remote_db_table.add("database", "wurker-remote.db")
        remote_db_table["database"].comment("Default: local sqlite file 'wurker-remote.db'")
        remote_db_table.add("dbdriver", "sqlite")
        remote_db_table["dbdriver"].comment("Default: 'sqlite'")
        remote_db_table.add("port", 0)

        config.add("remote_db", remote_db_table)

        # Write the configuration to the file
        with open(self.config_file, "w") as fh:
            tomlkit.dump(config, fh)
