import datetime
import json
import logging
import sys

from test_automation_suite.core.autologin import cleanup
from test_automation_suite.core.command_line_parser import argument_parser, print_pcb
from test_automation_suite.core.config import Config
from test_automation_suite.core.context import Context
from test_automation_suite.core.dump_test_results import dump_test_results
from test_automation_suite.core.logging import init_logging
from test_automation_suite.core.reboot import prepare_reboot
from test_automation_suite.core.task_dispatcher import TaskDispatcher

logger = logging.getLogger()


def main() -> None:
    # TODO: Maybe add a path here later and remove the default config in config.py
    task_dispatcher = TaskDispatcher()

    parser = argument_parser()
    args = parser.parse_args()

    config = Config.load(args.config) if args.config else Config()

    console_logging_level = logging.DEBUG if args.verbose else logging.INFO

    if not config.state_file.is_file():
        if args.command is None:
            parser.print_help()
            sys.exit(1)

        if args.command == "list":
            print_pcb(config)
            sys.exit(0)
        if args.command == "check":
            task_dispatcher.append_checks(args.check_name)
        if args.command == "benchmark":
            task_dispatcher.append_benchmarks(args.benchmark_name)
        if args.command == "run":
            task_dispatcher.load_procedure(config, args.procedure_name)
    else:
        if args.command is not None:
            print("The TAS has been interrupted before.")
            print("You can now")
            print("- delete the saved state and start a new run, or")
            print("- run the TAS without a command to resume the current run.")
            print(f"State file: {config.state_file}")
            sys.exit(1)
        task_dispatcher.load_persistent_state(config.state_file)

    config.output_base_directory.mkdir(parents=True, exist_ok=True)
    config.state_file.parent.mkdir(parents=True, exist_ok=True)
    config.dependency_installation_directory.mkdir(parents=True, exist_ok=True)

    timestamp = task_dispatcher.started_at.strftime("%Y-%m-%d_%H-%M-%S")
    context = Context(config=config, output_directory=config.output_base_directory / timestamp)
    context.output_directory.mkdir(parents=True, exist_ok=True)

    init_logging(context.output_directory, console_logging_level)

    logger.info("Started tests with configuration: %s", str(task_dispatcher))

    task_dispatcher.install_dependencies()

    if args.command == "run" and args.prepare_only:
        task_dispatcher.save_to_file(config.state_file)
        prepare_reboot()
        logger.info("running with no_first_run flag set, no Checks will be run")
        logger.info("reboot now to start the TAS")
        return

    task_dispatcher.run_tasks(context)

    cleanup(config)

    results_json = json.dumps(
        {
            "Test date": datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"),
            "Test results": {
                key: value.model_dump() for key, value in task_dispatcher.results.items()
            },
        },
        indent=4,
    )
    logger.info("Finished Testing with results: %s", results_json)

    dump_test_results(context, task_dispatcher, results_json)
