#!/usr/bin/env python
"""Run Trusty under QEMU in different configurations"""
import argparse
import fcntl
import json
import os
import re
import socket
import subprocess
import shutil
import sys
import tempfile
import time
import threading


# ADB expects its first console on 5554, and control on 5555
ADB_BASE_PORT = 5554


class RunnerError(Exception):
    """Contains all kinds of errors .run() will intentionally throw"""


class RunnerGenericError(RunnerError):
    """Generic runner error message"""
    def __init__(self, msg):
        super(RunnerGenericError, self).__init__()
        self.msg = msg

    def __str__(self):
        return "Runner failed: %s" % self.msg


class ConfigError(RunnerError):
    """Invalid configuration"""
    def __init__(self, msg):
        super(ConfigError, self).__init__()
        self.msg = msg

    def __str__(self):
        return "Invalid configuration: %s" % self.msg


class AdbFailure(RunnerError):
    """An adb invocation failed"""

    def __init__(self, adb_args, code):
        super(AdbFailure, self).__init__(self)
        self.adb_args = adb_args
        self.code = code

    def __str__(self):
        return "'adb %s' failed with %d" % (" ".join(self.adb_args), self.code)


class Timeout(RunnerError):
    """A step timed out"""

    def __init__(self, step, timeout):
        super(Timeout, self).__init__(self)
        self.step = step
        self.timeout = timeout

    def __str__(self):
        return "%s timed out (%d s)" % (self.step, self.timeout)


class Config(object):
    """Stores a QEMU configuration for use with the runner

    Attributes:
        android:          Path to a built Android tree or prebuilt.
        linux:            Path to a built Linux kernel tree or prebuilt.
        atf:              Path to the ATF build to use.
        qemu:             Path to the emulator to use
        rpmbd:            Path to the rpmb daemon to use.
        extra_qemu_flags: Extra flags to pass to QEMU.
    Setting android or linux to None will result in a QEMU which starts
    without those components.
    """

    def __init__(self, config=None):
        """Qemu Configuration

        If config is passed in, it should be a file containing a json
        specification fields described in the docs.
        Unspecified fields will be defaulted.

        If you do not pass in a config, you will almost always need to
        override these values; the default is not especially useful.
        """
        config_dict = {}
        if config:
            config_dict = json.load(config)

        self.android = config_dict.get("android")
        self.linux = config_dict.get("linux")
        self.atf = config_dict.get("atf")
        self.qemu = config_dict.get("qemu", "qemu-system-aarch64")
        self.rpmbd = config_dict.get("rpmbd")
        self.extra_qemu_flags = config_dict.get("extra_qemu_flags", [])


def alloc_ports():
    """Allocates 2 sequential ports above 5554 for adb"""
    # adb uses ports in pairs
    PORT_WIDTH = 2

    # We can't actually reserve ports atomically for QEMU, but we can at
    # least scan and find two that are not currently in use.
    min_port = ADB_BASE_PORT
    while True:
        alloced_ports = []
        for port in range(min_port, min_port + PORT_WIDTH):
            # If the port is already in use, don't hand it out
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect(("localhost", port))
                break
            except IOError:
                alloced_ports += [port]
        if len(alloced_ports) == PORT_WIDTH:
            return alloced_ports

        # We could increment by only 1, but if we are competing with other
        # adb sessions for ports, this will be more polite
        min_port += PORT_WIDTH


def forward_ports(ports):
    """Generates arguments to forward ports in QEMU on a virtio network"""
    forwards = []
    remap_port = ADB_BASE_PORT
    for port in ports:
        forwards += ["hostfwd=tcp::%d-:%d" % (port, remap_port)]
        remap_port = remap_port + 1
    return [
        "-device", "virtio-net,netdev=adbnet0", "-netdev",
        "user,id=adbnet0,%s" % ",".join(forwards)
    ]


def gen_command_dir():
    """Produces pipes for talking to QEMU and args to enable them"""
    command_dir = tempfile.mkdtemp()
    os.mkfifo("%s/com.in" % command_dir)
    os.mkfifo("%s/com.out" % command_dir)
    command_args = [
        "-chardev",
        "pipe,id=command0,path=%s/com" % command_dir, "-mon",
        "chardev=command0"
    ]
    return command_dir, command_args


def qemu_exit(command_dir, qemu_proc, has_error, debug_on_error):
    """Ensures QEMU is terminated"""
    unclean_exit = False

    if command_dir:
        # Ask QEMU to quit
        if qemu_proc and (qemu_proc.poll() is None):
            # Open O_NONBLOCK to deal with a potential race between
            # qemu_proc.poll() and the open call. The poll() is purely
            # advisory now.
            try:
                com_pipe = os.open("%s/com.in" % command_dir,
                                   os.O_NONBLOCK | os.O_WRONLY)
                if has_error:
                    os.write(com_pipe, "info registers -a\n")
                    if debug_on_error:
                        os.write(com_pipe, "gdbserver\n")
                        try:
                            raw_input("Connect gdb, press enter when done ")
                        except:
                            pass
                os.write(com_pipe, "quit\n")
                if has_error:
                    sys.stdout.flush()
                    sys.stderr.write("QEMU exit register dump:\n")
                    with open("%s/com.out" % command_dir, "r") as com_pipe_out:
                        for line in com_pipe_out:
                            if not (line.startswith("QEMU") or
                                    line.startswith("(qemu)")):
                                sys.stderr.write(line)
                os.close(com_pipe)
            except OSError:
                pass

            # If it doesn't die immediately, wait a second
            if qemu_proc.poll() is None:
                time.sleep(1)
                # If it's still not dead, take it out
                if qemu_proc.poll() is None:
                    qemu_proc.kill()
                    print "QEMU refused quit"
                    unclean_exit = True
            qemu_proc.wait()

        # Clean up our command pipe
        shutil.rmtree(command_dir)

    else:
        # This was an interactive run or a boot test
        # QEMU should not be running at this point
        if qemu_proc and (qemu_proc.poll() is None):
            print "QEMU still running with no command channel"
            qemu_proc.kill()
            qemu_proc.wait()
            unclean_exit = True
    return unclean_exit


class Runner(object):
    """Executes tests in QEMU"""

    MACHINE = "virt,secure=on,virtualization=on"

    BASIC_ARGS = [
        "-nographic", "-cpu", "cortex-a57", "-smp", "4", "-m", "1024", "-d",
        "unimp", "-semihosting-config", "enable,target=native", "-no-acpi",
        "-device", "virtio-serial",
    ]

    LINUX_ARGS = (
        "earlyprintk console=ttyAMA0,38400 keep_bootcon "
        "root=/dev/vda ro init=/init androidboot.hardware=qemu_trusty")

    def __init__(self,
                 config,
                 boot_tests=None,
                 android_tests=None,
                 interactive=False,
                 verbose=False,
                 rpmb=True,
                 debug=False,
                 debug_on_error=False):
        """Initializes the runner with provided settings.

        See .run() for the meanings of these.
        """
        self.config = config
        self.boot_tests = boot_tests if boot_tests else []
        self.android_tests = android_tests if android_tests else []
        self.interactive = interactive
        self.debug = debug
        self.verbose = verbose
        self.adb_transport = None
        self.temp_files = []
        self.use_rpmb = rpmb
        self.rpmb_proc = None
        self.rpmb_sock_dir = None
        self.debug_on_error = debug_on_error
        self.dump_stdout_on_error = False

        # Python 2.7 does not have subprocess.DEVNULL, emulate it
        devnull = open(os.devnull, "r+")
        # If we're not verbose or interactive, squelch command output
        if verbose or self.interactive:
            self.stdout = None
            self.stderr = None
        else:
            self.stdout = tempfile.TemporaryFile()
            self.stderr = subprocess.STDOUT
            self.dump_stdout_on_error = True

        # If we're interactive connect stdin to the user
        if self.interactive:
            self.stdin = None
        else:
            self.stdin = devnull

        if self.boot_tests and self.debug:
            print """\
Warning: Test selection does not work when --debug is set.
To run a test in test runner, run in GDB:

target remote :1234
break host_get_cmdline
c
next 6
set cmdline="boottest your.port.here"
set cmdline_len=sizeof("boottest your.port.here")-1
c
"""

    def error_dump_output(self):
        if self.dump_stdout_on_error:
            sys.stdout.flush()
            sys.stderr.write("System log:\n")
            self.stdout.seek(0)
            sys.stderr.write(self.stdout.read())

    def get_qemu_arg_temp_file(self):
        """Returns a temp file that will be deleted after qemu exits."""
        tmp = tempfile.NamedTemporaryFile(delete=False)
        self.temp_files.append(tmp.name)
        return tmp

    def drive_args(self, image, index):
        """Generates arguments for mapping a drive"""
        index_letter = chr(ord('a') + index)
        image_dir = "%s/out/target/product/trusty" % self.config.android
        return [
            "-drive",
            "file=%s/%s.img,index=%d,if=none,id=hd%s,format=raw,snapshot=on" %
            (image_dir, image, index, index_letter), "-device",
            "virtio-blk-device,drive=hd%s" % index_letter
        ]

    def android_drives_args(self):
        """Generates arguments for mapping all default drives"""
        args = []
        # This is order sensitive due to using e.g. root=/dev/vda
        args += self.drive_args("userdata", 2)
        args += self.drive_args("vendor", 1)
        args += self.drive_args("system", 0)
        return args

    def rpmb_up(self):
        """Brings up the rpmb daemon, returning QEMU args to connect"""
        rpmb_data = "%s/RPMB_DATA" % self.config.atf
        self.rpmb_sock_dir = tempfile.mkdtemp()
        rpmb_sock = "%s/rpmb" % self.rpmb_sock_dir
        rpmb_proc = subprocess.Popen([self.config.rpmbd,
                                      "-d", rpmb_data,
                                      "--sock", rpmb_sock])
        self.rpmb_proc = rpmb_proc

        # Wait for RPMB socket to appear to avoid a race with QEMU
        test_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        tries = 0
        max_tries = 10
        while True:
            tries += 1
            try:
                test_sock.connect(rpmb_sock)
                break
            except socket.error as exn:
                if tries >= max_tries:
                    raise exn
                time.sleep(1)

        return ["-device", "virtserialport,chardev=rpmb0,name=rpmb0",
                "-chardev", "socket,id=rpmb0,path=%s" % rpmb_sock]

    def rpmb_down(self):
        """Kills the running rpmb daemon, cleaning up its socket directory"""
        if self.rpmb_proc:
            self.rpmb_proc.kill()
            self.rpmb_proc = None
        if self.rpmb_sock_dir:
            shutil.rmtree(self.rpmb_sock_dir)
            self.rpmb_sock_dir = None

    def gen_dtb(self, args):
        """Computes a trusty device tree, returning a file for it"""
        with tempfile.NamedTemporaryFile() as dtb_gen:
            dump_dtb_cmd = [
                self.config.qemu, "-machine",
                "%s,dumpdtb=%s" % (self.MACHINE, dtb_gen.name)
            ] + [arg for arg in args if arg != "-S"]
            returncode = subprocess.call(dump_dtb_cmd)
            if returncode != 0:
                raise RunnerGenericError("dumping dtb failed with %d" %
                                         returncode)
            dtc = "%s/scripts/dtc/dtc" % self.config.linux
            dtb_to_dts_cmd = [dtc, "-q", "-O", "dts", dtb_gen.name]
            dtb_to_dts = subprocess.Popen(dtb_to_dts_cmd,
                                          stdout=subprocess.PIPE)
            dts = dtb_to_dts.communicate()[0]
            if dtb_to_dts.returncode != 0:
                raise RunnerGenericError("dtb_to_dts failed with %d" %
                                         dtb_to_dts.returncode)

        firmware = "%s/firmware.android.dts" % self.config.atf
        with open(firmware, "r") as firmware_file:
            dts += firmware_file.read()

        # Subprocess closes dtb, so we can't allow it to autodelete
        dtb = self.get_qemu_arg_temp_file()
        dts_to_dtb_cmd = [dtc, "-q", "-O", "dtb"]
        dts_to_dtb = subprocess.Popen(dts_to_dtb_cmd,
                                      stdin=subprocess.PIPE,
                                      stdout=dtb)
        dts_to_dtb.communicate(dts)
        dts_to_dtb_ret = dts_to_dtb.wait()
        if dts_to_dtb_ret:
            raise RunnerError("dts_to_dtb failed with %d" % dts_to_dtb_ret)
        return ["-dtb", dtb.name]

    def semihosting_run(self, args):
        """Runs QEMU assuming it will quit with semihosting"""
        args += [
            "-semihosting-config",
            "arg=boottest " + ",".join(self.boot_tests)
        ]

        # Prepend the serial port so that it is the *first* port and avoid
        # conflicting with rpmb0.
        if self.interactive:
            args = ["-serial", "mon:stdio"] + args
        elif self.verbose:
            # This still leaves stdin connected, but doesn't connect a monitor
            args = ["-serial", "stdio", "-monitor", "none"] + args
        else:
            # Silence debugging output
            args = ["-serial", "null", "-monitor", "none"] + args

        cmd = [self.config.qemu] + args
        # Test output is sent via semihosting, so don't disconnect stdout
        return subprocess.call(
            cmd,
            cwd=self.config.atf,
            stdin=self.stdin)

    def adb_bin(self):
        """Returns location of adb"""
        return "%s/out/host/linux-x86/bin/adb" % self.config.android

    def adb(self, args, timeout=60, force_output=False):
        """Runs an adb command

        If self.adb_transport is set, specializes the command to that
        transport to allow for multiple simultaneous tests.

        Timeout specifies a timeout for the command in seconds.

        If force_output is set true, will send results to stdout and
        stderr regardless of the runner's preferences.
        """
        if self.adb_transport:
            args = ["-t", "%d" % self.adb_transport] + args

        if force_output:
            stdout = None
            stderr = None
        else:
            stdout = self.stdout
            stderr = self.stderr

        adb_proc = subprocess.Popen(
            [self.adb_bin()] + args, stdin=self.stdin, stdout=stdout,
            stderr=stderr)

        # This code simulates the timeout= parameter due to no python 3

        def kill_adb():
            """Kills the running adb"""
            # Technically this races with wait - it is possible, though
            # unlikely, to get a spurious timeout message and kill
            # if .wait() returns, this function is triggered, and then
            # .cancel() runs
            adb_proc.kill()
            print "Timed out (%d s)" % timeout

        kill_timer = threading.Timer(timeout, kill_adb)
        kill_timer.start()
        # Add finally here so that the python interpreter will exit quickly
        # in the event of an exception rather than waiting for the timer
        try:
            exit_code = adb_proc.wait()
            return exit_code
        finally:
            kill_timer.cancel()


    def check_adb(self, args):
        """As .adb(), but throws an exception if the command fails"""
        code = self.adb(args)
        if code != 0:
            raise AdbFailure(args, code)

    def scan_transport(self, port, expect_none=False):
        """Given a port and `adb devices -l`, find the transport id"""
        output = subprocess.check_output([self.adb_bin(), "devices", "-l"])
        match = re.search(r"localhost:%d.*transport_id:(\d+)" % port, output)
        if not match:
            if expect_none:
                self.adb_transport = None
                return
            print "Failed to find transport for port %d in \n%s" % (port,
                                                                    output)
        self.adb_transport = int(match.group(1))

    def adb_up(self, port):
        """Ensures adb is connected to adbd on the selected port"""
        # Wait until we can connect to the target port
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        CONNECT_MAX_TRIES = 15
        connect_tries = 0
        while True:
            try:
                sock.connect(("localhost", port))
                break
            except IOError:
                connect_tries += 1
                if connect_tries >= CONNECT_MAX_TRIES:
                    raise Timeout("Wait for adbd socket", CONNECT_MAX_TRIES)
                time.sleep(1)
        sock.close()
        self.check_adb(["connect", "localhost:%d" % port])
        self.scan_transport(port)
        self.check_adb(["wait-for-device"])
        self.check_adb(["root"])
        self.check_adb(["wait-for-device"])

        # Files put onto the data partition in the Android build will not
        # actually be populated into userdata.img when make dist is used.
        # To work around this, we manually update /data once the device is
        # booted by pushing it the files that would have been there.
        userdata = "%s/out/target/product/trusty/data" % self.config.android
        self.check_adb(["push", userdata, "/"])

    def adb_down(self, port):
        """Cleans up after adb connection to adbd on selected port"""
        self.check_adb(["disconnect", "localhost:%d" % port])

        # Wait until QEMU's forward has expired
        CONNECT_MAX_TRIES = 15
        connect_tries = 0
        while True:
            try:
                self.scan_transport(port, expect_none=True)
                if not self.adb_transport:
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.connect(("localhost", port))
                    sock.close()
                connect_tries += 1
                if connect_tries >= CONNECT_MAX_TRIES:
                    raise Timeout("Wait for port forward to go away",
                                  CONNECT_MAX_TRIES)
                time.sleep(1)
            except IOError:
                break

    def check_config(self):
        """Checks the runner/qemu config to make sure they are compatible"""
        # If we have any android tests, we need a linux dir and android dir
        if self.android_tests:
            if not self.config.linux:
                raise ConfigError("Need Linux to run android tests")
            if not self.config.android:
                raise ConfigError("Need Android to run android tests")

        # For now, we can't run boot tests and android tests at the same time,
        # because test-runner reports its exit code by terminating the
        # emulator.
        if self.android_tests:
            if self.boot_tests:
                raise ConfigError("Cannot run Android tests and boot"
                                  " tests from same runner")

        # Since boot_tests exit the machine with semihosting, it is not
        # compatible with interactive mode.
        if self.boot_tests:
            if self.interactive:
                raise ConfigError("Cannot run boot tests interactively")

        if self.config.android:
            if not self.config.linux:
                raise ConfigError("Cannot run Android without Linux")

    def universal_args(self):
        """Generates arguments used in all qemu invocations"""
        args = list(self.BASIC_ARGS)
        # Set ATF to be the bios
        args += ["-bios", "%s/bl1.bin" % self.config.atf]

        if self.config.linux:
            args += [
                "-kernel",
                "%s/arch/arm64/boot/Image" % self.config.linux
            ]
            args += ["-append", self.LINUX_ARGS]

        if self.config.android:
            args += self.android_drives_args()

        # Append configured extra flags
        args += self.config.extra_qemu_flags

        return args

    def run(self):
        """Launches the QEMU execution.

        Runs boot_tests through test_runner, android_tests through ADB,
        returning aggregated test return codes in a list.

        If interactive is specified, it will leave the user connected
        to the serial console/monitor, and they are responsible for
        terminating execution.

        If debug is on, the main QEMU instance will be launched with -S and
        -s, which pause the CPU rather than booting, and starts a gdb server
        on port 1234 respectively.

        Note that if the boot_tests is specified, that argument will not be
        correctly read because semihosting-config does not work under the
        debugger.

        Returns:
          A list of return codes for the provided tests.
          A negative return code indicates an internal tool failure.

        Limitations:
          Until test_runner is updated, only one of android_tests or boot_tests
          may be provided.
          Similarly, while boot_tests is a list, test_runner only knows how to
          correctly run a single test at a time.
          Again due to test_runner's current state, if boot_tests are
          specified, interactive will be ignored since the machine will
          terminate itself.

          If android_tests is provided, a Linux and Android dir must be
          provided in the config.

          If the adb port range is already in use, port forwarding may fail.
        """
        self.check_config()

        ports = None

        args = self.universal_args()

        test_results = []
        command_dir = None

        qemu_proc = None
        has_error = False

        # Resource exists in multiple functions, wants to use the same
        # cleanup block regardless
        self.temp_files = []

        try:
            if self.use_rpmb:
                args += self.rpmb_up()

            if self.config.linux:
                args += self.gen_dtb(args)

            # Prepend the machine since we don't need to edit it as in gen_dtb
            args = ["-machine", self.MACHINE] + args

            if self.debug:
                args += ["-s", "-S"]

            # This codepath should go away when test_runner is changed to
            # not use semihosting exit to report
            if self.boot_tests:
                return [self.semihosting_run(args)]

            # Logging and terminal monitor
            # Prepend so that it is the *first* serial port and avoid
            # conflicting with rpmb0.
            args = ["-serial", "mon:stdio"] + args

            # If we're noninteractive (e.g. testing) we need a command channel
            # to tell the guest to exit
            if not self.interactive:
                command_dir, command_args = gen_command_dir()
                args += command_args

            # Reserve ADB ports
            ports = alloc_ports()
            # Forward ADB ports in qemu
            args += forward_ports(ports)

            qemu_cmd = [self.config.qemu] + args
            qemu_proc = subprocess.Popen(
                qemu_cmd,
                cwd=self.config.atf,
                stdin=self.stdin,
                stdout=self.stdout,
                stderr=self.stderr)

            if self.debug:
                print "Run gdb and \"target remote :1234\" to debug"

            try:
                # Bring ADB up talking to the command port
                self.adb_up(ports[1])

                # Run android tests
                for android_test in self.android_tests:
                    test_result = self.adb(["shell", android_test],
                                           timeout=(60 * 10),
                                           force_output=True)
                    test_results.append(test_result)
                    if test_result:
                        has_error = True
                        break
            # Finally is used here to ensure that ADB failures do not take away
            # the user's serial console in interactive mode.
            finally:
                if self.interactive:
                    # The user is responsible for quitting QEMU
                    qemu_proc.wait()
        except:
            has_error = True
            raise
        finally:
            # Clean up generated device tree
            for temp_file in self.temp_files:
                os.remove(temp_file)

            if has_error:
                self.error_dump_output()

            unclean_exit = qemu_exit(command_dir, qemu_proc,
                                     has_error=has_error,
                                     debug_on_error=self.debug_on_error)

            fcntl.fcntl(0, fcntl.F_SETFL,
                        fcntl.fcntl(0, fcntl.F_GETFL) & ~os.O_NONBLOCK)

            self.rpmb_down()

            if self.adb_transport:
                # Disconnect ADB and wait for our port to be released by qemu
                self.adb_down(ports[1])

            if unclean_exit:
                raise RunnerGenericError("QEMU did not exit cleanly")
        return test_results


def main():
    argument_parser = argparse.ArgumentParser()
    argument_parser.add_argument("-c", "--config", type=file)
    argument_parser.add_argument("--headless", action="store_true")
    argument_parser.add_argument("-v", "--verbose", action="store_true")
    argument_parser.add_argument("--debug", action="store_true")
    argument_parser.add_argument("--debug-on-error", action="store_true")
    argument_parser.add_argument("--boot-test", action="append")
    argument_parser.add_argument("--shell-command", action="append")
    argument_parser.add_argument("--android")
    argument_parser.add_argument("--linux")
    argument_parser.add_argument("--atf")
    argument_parser.add_argument("--qemu")
    argument_parser.add_argument("--disable-rpmb", action="store_true")
    argument_parser.add_argument("extra_qemu_flags", nargs="*")
    args = argument_parser.parse_args()

    config = Config(args.config)
    if args.android:
        config.android = args.android
    if args.linux:
        config.linux = args.linux
    if args.atf:
        config.atf = args.atf
    if args.qemu:
        config.qemu = args.qemu
    if args.extra_qemu_flags:
        config.extra_qemu_flags += args.extra_qemu_flags

    runner = Runner(config, boot_tests=args.boot_test,
                    android_tests=args.shell_command,
                    interactive=not args.headless,
                    verbose=args.verbose,
                    rpmb=not args.disable_rpmb,
                    debug=args.debug,
                    debug_on_error=args.debug_on_error)

    try:
        results = runner.run()
        print "Command results: %r" % results

        if any(results):
            sys.exit(1)
        else:
            sys.exit(0)
    except RunnerError as exn:
        print exn
        sys.exit(2)


if __name__ == "__main__":
    main()
