import shutil
import sys
import tomllib

from wox.constants import DOT_WOX, ExitCode
from wox.main import main
from wox.utils import auto_clean_logs
from wox.wox_exceptions import (
    ConfigFileNotFoundError,
    MissingWoxKeywordError,
    MissingWoxSectionError,
    NoTaskError,
    TaskNotFoundError,
    WoxException
)
from wox.wox_steward import WoxSteward


def cli_controller(cli_options):
    """
        Processes cli options to make them compatible with the execution
        of wox runner, then starts the wox session.

        Parameters
        ----------
        cli_options : dict
            Contains options provided by the user in command-line.

        Returns
        -------
        exit_code : int

        Raises
        ------
        Exception
            Any exception not handled by wox.
    """

    wox_steward = WoxSteward()
    wox_steward.dot_wox_setup()

    if cli_options.get('purge'):
        wox_steward.purge_wox()
        print('.wox directory successfully purged.')
        return ExitCode.SUCCESS.value

    try:
        return main(cli_options, wox_steward.wox_data)
    except (
        ConfigFileNotFoundError,
        MissingWoxSectionError,
        MissingWoxKeywordError,
        NoTaskError,
        TaskNotFoundError,
        tomllib.TOMLDecodeError
    ) as e:
        if isinstance(e, WoxException):
            print(e)
        else:
            print(f'{e.__class__.__name__}: {e}')

        if 'pytest' not in sys.modules:
            auto_clean_logs()

        # handling case when wox is executed naively for the first time
        if (
            isinstance(e, ConfigFileNotFoundError) or \
            isinstance(e, MissingWoxSectionError)
        ):
            logs_dir = DOT_WOX / '.logs'
            if not any(path.is_file() for path in logs_dir.rglob('*')):
                shutil.rmtree(DOT_WOX)

        return ExitCode.CONFIG_ERROR.value
    except KeyboardInterrupt:
        print('Wox session aborted by user.')
        return ExitCode.INTERRUPTED.value
    except Exception:
        if 'pytest' not in sys.modules:
            auto_clean_logs()
        raise
