#! /usr/bin/env python3

import itertools
import os
import pathlib
import signal
import sys
import threading

import logging
logger = logging.getLogger("RunFVP")

# Add meta-arm/lib/ to path
libdir = pathlib.Path(__file__).parents[1] / "meta-arm" / "lib"
sys.path.insert(0, str(libdir))

from fvp import terminal, runner, conffile

def parse_args(arguments):
    import argparse
    terminals = terminal.terminals

    parser = argparse.ArgumentParser(description="Run images in a FVP")
    parser.add_argument("config", nargs="?", help="Machine name or path to .fvpconf file")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-t", "--terminals", choices=terminals.all_terminals(), default=terminals.preferred_terminal(), help="Automatically start terminals (default: %(default)s)")
    group.add_argument("-c", "--console", action="store_true", help="Attach the first uart to stdin/stdout")
    parser.add_argument("--verbose", action="store_true", help="Output verbose logging")
    parser.usage = f"{parser.format_usage().strip()} -- [ arguments passed to FVP ]"
    # TODO option for telnet vs netcat

    # If the arguments contains -- then everything after it should be passed to the FVP binary directly.
    if "--" in arguments:
        i = arguments.index("--")
        fvp_args = arguments[i+1:]
        arguments = arguments[:i]
    else:
        fvp_args = []

    args = parser.parse_args(args=arguments)
    logging.basicConfig(level=args.verbose and logging.DEBUG or logging.WARNING,
                        format='\033[G%(levelname)s: %(message)s')

    # If we're hooking up the console, don't start any terminals
    if args.console:
        args.terminals = "none"

    logger.debug(f"Parsed arguments: {vars(args)}")
    logger.debug(f"FVP arguments: {fvp_args}")
    return args, fvp_args

def start_fvp(args, config, extra_args):
    fvp = runner.FVPRunner(logger)
    try:
        fvp.start(config, extra_args, args.terminals)

        if args.console:
            expected_terminal = config["consoles"]["default"]
            if not expected_terminal:
                logger.error("--console used but FVP_CONSOLE not set in machine configuration")
                return 1
            port_stdout, log_stdout = itertools.tee(fvp.stdout, 2)
            parser = runner.ConsolePortParser(port_stdout)
            port = parser.parse_port(expected_terminal)

            def debug_log():
                for line in log_stdout:
                    line = line.strip().decode(errors='ignore')
                    logger.debug(f'FVP output: {line}')
            log_thread = threading.Thread(None, debug_log)
            log_thread.start()

            telnet = fvp.create_telnet(port)
            telnet.wait()
            logger.debug(f"Telnet quit, cancelling tasks")
        else:
            for line in fvp.stdout:
                print(line.strip().decode(errors='ignore'))

    finally:
        fvp.stop()


def runfvp(cli_args):
    args, extra_args = parse_args(cli_args)
    if args.config and pathlib.Path(args.config).exists():
        config_file = args.config
    else:
        config_file = conffile.find(args.config)
    logger.debug(f"Loading {config_file}")
    config = conffile.load(config_file)
    start_fvp(args, config, extra_args)


if __name__ == "__main__":
    try:
        # Set the process group so that it's possible to kill runfvp and
        # everything it spawns easily.
        # Ignore permission errors happening when spawned from an other process
        # for example run from except
        try:
            os.setpgid(0, 0)
        except PermissionError:
            pass
        if sys.stdin.isatty():
            signal.signal(signal.SIGTTOU, signal.SIG_IGN)
            os.tcsetpgrp(sys.stdin.fileno(), os.getpgrp())
        sys.exit(runfvp(sys.argv[1:]))
    except KeyboardInterrupt:
        pass
