#! /usr/bin/env python3
import getopt
import logging
import os
import sys
import yaml


import aj
import aj.config
import aj.entry
import aj.log
import aj.plugins


# Is the ajenti virtualenv installed ?
panel_venv = '/opt/ajenti/bin/ajenti-panel'
if os.path.isfile(panel_venv) and os.path.abspath(__file__) != panel_venv:
    logging.info('Ajenti virtualenv detected, switching to it.')
    try:
        os.execv(panel_venv, sys.argv)
    except Exception:
        logging.error('Unable to start ajenti virtualenv, continuing with global python.')

class AjentiConfig(aj.config.BaseConfig):
    def __init__(self, path):
        aj.config.BaseConfig.__init__(self)
        self.data = None
        self.path = os.path.abspath(path)

    def __str__(self):
        return self.path

    def load(self):
        if os.geteuid() == 0:
            os.chmod(self.path, 384)  # 0o600
        self.data = yaml.load(open(self.path), Loader=yaml.Loader)

    def save(self):
        with open(self.path, 'w') as f:
            f.write(yaml.safe_dump(self.data, default_flow_style=False, encoding='utf-8', allow_unicode=True).decode('utf-8'))


def usage():
    print(f"""
Usage: {sys.argv[0]} [options]
Options:
    -c, --config <file> - Use given config file instead of default
    -v                  - Debug/verbose logging ( shortcut for --log debug )
    --dev               - Dev mode (recompile resources)
    -d, --daemon        - Run in background (daemon mode)
    --stock-plugins     - Load plugins from PYTHONPATH
    --plugins <dir>     - Load plugins from a directory
    --autologin         - Log in automatically as the running user
    --log '<level>'     - Fix log level : debug, info, warning or error
    -h, --help          - This help
    """)


if __name__ == '__main__':
    log_levels = {"debug": logging.DEBUG, "info": logging.INFO, "warning": logging.WARNING, "error": logging.ERROR}
    log_level = logging.INFO
    daemonize = False
    dev_mode = False
    debug_mode = False
    config_path = None
    autologin = False
    plugin_providers = []

    try:
        opts, args = getopt.getopt(
            sys.argv[1:],
            'hc:dv',
            ['help', 'config=', 'daemon', 'dev', 'stock-plugins', 'plugins=', 'autologin', 'log=']
        )
    except getopt.GetoptError as e:
        print(str(e))
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            sys.exit(0)
        elif o in ('-v',):
            log_level = logging.DEBUG
            debug_mode = True
        elif o in ('--dev',):
            log_level = logging.DEBUG
            debug_mode = True
            dev_mode = True
        elif o in ('--log',):
            log_level = log_levels[a]
        elif o in ('-c', '--config'):
            config_path = a
        elif o in ('-d', '--start'):
            daemonize = True
        elif o in ('--autologin',):
            autologin = True
        elif o == '--stock-plugins':
            plugin_providers.append(aj.plugins.PythonPathPluginProvider())
        elif o == '--plugins':
            plugin_providers.append(aj.plugins.DirectoryPluginProvider(a))

    if not plugin_providers:
        plugin_providers.append(aj.plugins.PythonPathPluginProvider())

    aj.log.init_console(log_level)

    if autologin and not debug_mode:
        logging.error('Autologin is a dangerous option and should be used together with -v')
        sys.exit(1)

    # Find default config file
    if not config_path:
        # Check for config file in /etc/ajenti/config.yml
        if os.path.isfile('/etc/ajenti/config.yml'):
            config_path = '/etc/ajenti/config.yml'
        elif os.path.isfile(os.path.join(sys.path[0], 'config.yml')):
            # Try local config file
            config_path = os.path.join(sys.path[0], 'config.yml')

    if not os.path.exists(config_path):
        logging.error(f'Config file "{config_path}" not found')
        sys.exit(1)

    aj.entry.start(
        config=AjentiConfig(config_path),
        dev_mode=dev_mode,
        debug_mode=debug_mode,
        autologin=autologin,
        product_name='ajenti',
        daemonize=daemonize,
        plugin_providers=plugin_providers,
        log_level=log_level,
    )
