#! /usr/bin/env python3

import asyncio
import os
import pathlib
import signal
import sys

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)

    # 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


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

        if args.console:
            fvp.add_line_callback(lambda line: logger.debug(f"FVP output: {line}"))
            expected_terminal = config["consoles"]["default"]
            if not expected_terminal:
                logger.error("--console used but FVP_CONSOLE not set in machine configuration")
                return 1
            telnet = await fvp.create_telnet(expected_terminal)
            await telnet.wait()
            logger.debug(f"Telnet quit, cancelling tasks")
        else:
            fvp.add_line_callback(lambda line: print(line))
            await fvp.run()

    finally:
        await 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)

    try:
        # When we can assume Py3.7+, this can simply be asyncio.run()
        loop = asyncio.get_event_loop()
        return loop.run_until_complete(start_fvp(args, config, extra_args))
    except asyncio.CancelledError:
        # This means telnet exited, which isn't an error
        return 0

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
