#!/usr/bin/env python3

""" fvp_dispatcher.py:

    Fastmodel dispatcher takes an build report input from build_helper and
    selects the appropriate tests, lauched in separate fastmodel Wrapper
    instances """

from __future__ import print_function

__copyright__ = """
/*
 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */
 """
__author__ = "Minos Galanakis"
__email__ = "minos.galanakis@linaro.org"
__project__ = "Trusted Firmware-M Open CI"
__status__ = "stable"
__version__ = "1.1"

import os
import sys
import argparse
from copy import deepcopy
from fastmodel_dispatcher_configs import fvp_config_map

try:
    from tfm_ci_pylib.utils import load_json, print_test, save_json, \
        show_progress
    from tfm_ci_pylib.fastmodel_wrapper import FastmodelWrapper
    from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager

except ImportError:
    dir_path = os.path.dirname(os.path.realpath(__file__))
    sys.path.append(os.path.join(dir_path, "../"))
    from tfm_ci_pylib.utils import load_json, print_test, save_json, \
        show_progress
    from tfm_ci_pylib.fastmodel_wrapper import FastmodelWrapper
    from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager


def cfilter(config_list, match):
    """Filter a list of items in _text1_text2_ format and only include
    results who contain the match term between two underscores """

    # Ensure the match has the format of _text_
    match = "_%s_" % match.strip("_")

    return [n for n in config_list if match in n]


def main(user_args):
    """ Main logic """

    test_config_list = None

    if user_args.list_cfg:
        print("Built-in configs:")
        print("\n".join(fvp_config_map.list()))
        sys.exit(0)
    elif user_args.single_cfg:
        try:
            # Try to fetch the config to validate it exists
            fvp_config_map.get_config(user_args.single_cfg)
            test_config_list = [user_args.single_cfg]
        except Exception as e:
            print("Error: %s" % e)
            sys.exit(1)
    elif user_args.build_all:
        test_config_list = fvp_config_map.list()
    # If a build report is provided parse it
    elif user_args.build_report:
        build_report = load_json(user_args.build_report)

        build_cfg = build_report["_metadata_"]["input_build_cfg"]

        # build and test configs share common key name enties
        config_list = list(map(str.lower,
                               (map(str, build_report["report"].keys()))))

        # Only choose the tests that have been defined in the map
        test_config_list = [n for n in fvp_config_map.list()
                            if n in config_list]

        # Use the Build manager to calcuate the rejection list in the same
        # manner.
        rj = TFM_Build_Manager.generate_rejection_list(
            build_cfg["seed_params"],
            build_cfg["common_params"],
            fvp_config_map.get_invalid()).keys()

        # Remove every config that is included in the rejection.
        # Ignore generated rejection configs that have not been set in the
        # test map.
        for name in rj:
            name = name.lower()
            try:
                test_config_list.pop(test_config_list.index(name))
                print("Rejecting config %s" % name)
            except Exception as e:
                print("Rejection ignored with exception:", e)
    else:
        print("Noting to do. Please provide a report or a config name to test")
        sys.exit(1)

    # Apply filters if specified by user
    if user_args.build_armclang:
        test_config_list = cfilter(test_config_list, "armclang")
    elif user_args.build_gnuarm:
        test_config_list = cfilter(test_config_list, "gnuarm")
    elif user_args.filter:
        test_config_list = cfilter(test_config_list, user_args.filter)
    else:
        pass

    print("Working on Test list: \n%s" % "\n".join(sorted(test_config_list)))

    if user_args.p_command:

        for test_cfg in test_config_list:

            test_cfg_obj = fvp_config_map.get_config_object(test_cfg)
            _tmp_cfg = FastmodelWrapper(fvp_cfg=test_cfg_obj.get_config())

            print("\nCommand line:")
            print("")
            _tmp_cfg.show_cmd()
            print("\n")
        sys.exit(0)

    # Run tests
    rep = []
    test_count = 0
    for test_cfg in test_config_list:

        # Check if the config hardcoded binary path is same as the one
        # in the build report. If not update the config
        test_cfg_obj = fvp_config_map.get_config_object(test_cfg)

        rep.append(FastmodelWrapper(
                   fvp_cfg=test_cfg_obj.get_config())
                   .start().block_wait().test().save_report().get_report())
        test_count += 1
        print("Testing progress:")
        show_progress(test_count, len(test_config_list))

    # Export the report in a file
    if user_args.report:
        f_report = {"report": {}, "_metadata_": {}}
        f_report["report"] = {k["name"]: deepcopy(k) for k in rep}
        save_json(user_args.report, f_report)

    sl = [x["name"] for x in rep if x["success"] is True]
    fl = [x["name"] for x in rep if x["success"] is False]

    print("\n")

    if sl:
        print_test(t_list=sl, status="passed", tname="Tests")
    if fl:
        print_test(t_list=fl, status="failed", tname="Tests")
        if user_args.eif:
            sys.exit(1)


def get_cmd_args():
    """ Parse command line arguments """

    # Parse command line arguments to override config
    parser = argparse.ArgumentParser(description="TFM Fastmodel wrapper.")
    parser.add_argument("-b", "--build_report",
                        dest="build_report",
                        action="store",
                        help="JSON file produced by build_helper (input)")
    parser.add_argument("-a", "--build_all",
                        dest="build_all",
                        action="store_true",
                        help="If set build every configuration combination")
    parser.add_argument("-e", "--error_if_failed",
                        dest="eif",
                        action="store_true",
                        help="If set will change the script exit code if one "
                              "or more tests fail")
    parser.add_argument("-r", "--report",
                        dest="report",
                        action="store",
                        help="JSON file containing fastmodel report (output)")
    parser.add_argument("-g", "--build_gnuarm",
                        dest="build_gnuarm",
                        action="store_true",
                        help="If set build every gnuarm configuration")
    parser.add_argument("-c", "--build_armclang",
                        dest="build_armclang",
                        action="store_true",
                        help="If set build every armclang configuration")
    parser.add_argument("-f", "--filter",
                        dest="filter",
                        action="store",
                        help="Only select configs that contain this string")
    parser.add_argument("-l", "--list-configs",
                        dest="list_cfg",
                        action="store_true",
                        help="Print a list of the built-in configurations and"
                             "exit")
    parser.add_argument("-s", "--single-config",
                        dest="single_cfg",
                        action="store",
                        help="Launch testing for a single built-in config,  "
                              "picked by name")
    parser.add_argument("-p", "--print-command",
                        dest="p_command",
                        action="store_true",
                        help="Print the FPV launch command to console & exit")
    return parser.parse_args()


if __name__ == "__main__":
    main(get_cmd_args())
