#!/usr/bin/env python3
"""
    CIJOE Test Runner
"""
import argparse
import tempfile
import uuid
import sys
import os
import cij.runner
import cij.util
import cij


def parse_args():
    """Parse command-line arguments for cij_runner"""

    prsr = argparse.ArgumentParser(
        description="cij_runner - CIJOE Test Runner",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    prsr.register('action', 'custom_extend', cij.util.ExtendAction)
    prsr.add_argument(
        "--testplan",
        help="Path to one or more testplan(s) to run",
        action="custom_extend",
        nargs="+",
        required=True,
        type=str
    )
    prsr.add_argument(
        "--env",
        required=True,
        help="Path to the environment definition",
    )
    prsr.add_argument(
        "--output",
        help="Path to directory in which to store runner output",
        default=os.path.join("/tmp", "trun-%s" % str(uuid.uuid4())[:8])
    )
    prsr.add_argument(
        "--testcase-match",
        help="run only testcases matching the given string"
    )
    prsr.add_argument(
        "-v", "--verbose",
        help="increase output verbosity, 0 = quiet, 1 = some, 1 > alot",
        action="count",
        default=0
    )

    return prsr.parse_args()


def main(args):
    """
    Parse environment variables and command-line arguments constructing a
    configuration for which to invoke the runner
    """

    conf = cij.conf.from_system()
    if conf is None:
        cij.err("rprt: failed retrieving CIJOE configuration")
        return None

    args.testplans = []
    for path in args.testplan:
        tplan_fpath = cij.util.expand_path(path)

        if not os.path.exists(tplan_fpath):
            cij.err("TESTPLAN_FPATH: %r, does not exist" % tplan_fpath)
            return 1

        args.testplans.append(tplan_fpath)

    # Setup path to env script
    args.env_fpath = cij.util.expand_path(args.env)

    if not os.path.exists(args.env_fpath):
        cij.err("env_fpath: %r, does not exist" % args.env_fpath)
        return 1

    args.env_fname = os.path.basename(args.env_fpath)
    args.env_name = ".".join(args.env_fname.split(".")[:-1])
    args.output = cij.util.expand_path(args.output)

    if not os.path.exists(args.output):
        try:
            os.makedirs(args.output)
        except OSError as exc:
            cij.err("rnr: FAILED: makedirs OUTPUT: %r, exc: %r" % (
                args.output, exc
            ))
            return 1

    cij.warn("rnr: { OUTPUT: %r }" % args.output)

    rcode = cij.runner.main(args, conf)
    if rcode:
        cij.err("rnr: rcode: %r" % rcode)

    cij.warn("rnr: { OUTPUT: %r }" % args.output)

    return rcode


if __name__ == "__main__":
    ARGS = parse_args()

    LOCK_NAME = os.path.basename(ARGS.env).replace('.', '_')
    FNAME = os.path.join(tempfile.gettempdir(), LOCK_NAME + "_cijoe.lock")
    try:
        with open(FNAME, "x", encoding="UTF-8") as fd:
            RES = main(ARGS)
        os.remove(FNAME)

        sys.exit(RES)
    except FileExistsError:
        cij.err("---------==========={[ CIJOE IS LOCKED ]}==========---------")
        cij.warn("Looks like CIJOE is already running")
        cij.warn("or, a previous run did unclean exit")
        cij.warn("Clean up the target-system-under-test reboot / provision")
        cij.warn("Then remove '%s' and start the runner again" % FNAME)
        cij.err("---------==========={[ CIJOE IS LOCKED ]}==========---------")
    except KeyboardInterrupt:
        cij.err("---------============{[ UNCLEAN EXIT ]}===========---------")
        cij.warn(" ")
        cij.warn(" Runner was killed by keyboard-interrupt e.g. Ctrl+C")
        cij.warn(" ")
        cij.warn(" Target is tainted as processes are likely to still be")
        cij.warn(" running on the target.")
        cij.warn(" ")
        cij.warn(" To start the runner again, do the following")
        cij.warn(" ")
        cij.warn(" 1) Ensure the target is sound, e.g. reboot / provision")
        cij.warn(" 2) Remove the lock: '%s'" % FNAME)
        cij.warn(" 3) Start the runner")
        cij.err("---------============{[ UNCLEAN EXIT ]}===========---------")
