#!/usr/bin/env python2
#
# Copyright (c) 2016 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Andreas Sandberg

import argparse
import sys
import os
import pickle

from testing.tests import *
import testing.results

class ParagraphHelpFormatter(argparse.HelpFormatter):
    def _fill_text(self, text, width, indent):
        return "\n\n".join([
            super(ParagraphHelpFormatter, self)._fill_text(p, width, indent) \
            for p in text.split("\n\n") ])

formatters = {
    "junit" : testing.results.JUnit,
    "text" : testing.results.Text,
    "summary" : testing.results.TextSummary,
    "pickle" : testing.results.Pickle,
}


def _add_format_args(parser):
    parser.add_argument("--format", choices=formatters, default="text",
                        help="Output format")

    parser.add_argument("--no-junit-xlate-names", action="store_true",
                        help="Don't translate test names to " \
                        "package-like names")

    parser.add_argument("--output", "-o",
                        type=argparse.FileType('w'), default=sys.stdout,
                        help="Test result output file")


def _create_formatter(args):
    formatter = formatters[args.format]
    kwargs = {
        "fout" : args.output,
        "verbose" : args.verbose
    }

    if issubclass(formatter, testing.results.JUnit):
        kwargs.update({
            "translate_names" : not args.no_junit_xlate_names,
        })

    return formatter(**kwargs)


def _list_tests_args(subparsers):
    parser = subparsers.add_parser(
        "list",
        formatter_class=ParagraphHelpFormatter,
        help="List available tests",
        description="List available tests",
        epilog="""
        Generate a list of available tests using a list filter.

        The filter is a string consisting of the target ISA optionally
        followed by the test category and mode separated by
        slashes. The test names emitted by this command can be fed
        into the run command.

        For example, to list all quick arm tests, run the following:
        tests.py list arm/quick

        Non-mandatory parts of the filter string (anything other than
        the ISA) can be left out or replaced with the wildcard
        character. For example, all full-system tests can be listed
        with this command: tests.py list arm/*/fs""")

    parser.add_argument("--ruby-protocol", type=str, default=None,
                        help="Ruby protocol")

    parser.add_argument("--gpu-isa", type=str, default=None,
                        help="GPU ISA")

    parser.add_argument("list_filter", metavar="ISA[/category/mode]",
                        action="append", type=str,
                        help="List available test cases")

def _list_tests(args):
    for isa, categories, modes in \
        ( parse_test_filter(f) for f in args.list_filter ):

        for test in get_tests(isa, categories=categories, modes=modes,
                              ruby_protocol=args.ruby_protocol,
                              gpu_isa=args.gpu_isa):
            print "/".join(test)
    sys.exit(0)

def _run_tests_args(subparsers):
    parser = subparsers.add_parser(
        "run",
        formatter_class=ParagraphHelpFormatter,
        help='Run one or more tests',
        description="Run one or more tests.",
        epilog="""
        Run one or more tests described by a gem5 test tuple.

        The test tuple consists of a test category (quick or long), a
        test mode (fs or se), a workload name, an isa, an operating
        system, and a config name separate by slashes. For example:
        quick/se/00.hello/arm/linux/simple-timing

        Available tests can be listed using the 'list' sub-command
        (e.g., "tests.py list arm/quick" or one of the scons test list
        targets (e.g., "scons build/ARM/tests/opt/quick.list").

        The test results can be stored in multiple different output
        formats. See the help for the show command for more details
        about output formatting.""")

    parser.add_argument("gem5", type=str,
                        help="gem5 binary")

    parser.add_argument("test", type=str, nargs="*",
                        help="List of tests to execute")

    parser.add_argument("--directory", "-d",
                        type=str, default="m5tests",
                        help="Test work directory")

    parser.add_argument("--timeout", "-t",
                        type=int, default="0", metavar="MINUTES",
                        help="Timeout, 0 to disable")

    parser.add_argument("--skip-diff-out", action="store_true",
                        help="Skip output diffing stage")

    parser.add_argument("--skip-diff-stat", action="store_true",
                        help="Skip stat diffing stage")

    _add_format_args(parser)

def _run_tests(args):
    if not os.path.isfile(args.gem5) or not os.access(args.gem5, os.X_OK):
        print >> sys.stderr, \
            "gem5 binary '%s' not an executable file" % args.gem5
        sys.exit(2)

    formatter = _create_formatter(args)

    out_base = os.path.abspath(args.directory)
    if not os.path.exists(out_base):
        os.mkdir(out_base)
    tests = []
    for test_name in args.test:
        config = ClassicConfig(*test_name.split("/"))
        out_dir = os.path.join(out_base, "/".join(config))
        tests.append(
            ClassicTest(args.gem5, out_dir, config,
                        timeout=args.timeout,
                        skip_diff_stat=args.skip_diff_stat,
                        skip_diff_out=args.skip_diff_out))

    all_results = []
    print "Running %i tests" % len(tests)
    for testno, test in enumerate(tests):
        print "%i: Running '%s'..." % (testno, test)

        all_results.append(test.run())

    formatter.dump_suites(all_results)

def _show_args(subparsers):
    parser = subparsers.add_parser(
        "show",
        formatter_class=ParagraphHelpFormatter,
        help='Display pickled test results',
        description='Display pickled test results',
        epilog="""
        Reformat the pickled output from one or more test runs. This
        command is typically used with the output from a single test
        run, but it can also be used to merge the outputs from
        multiple runs.

        The 'text' format is a verbose output format that provides
        information about individual test units and the output from
        failed tests. It's mainly useful for debugging test failures.

        The 'summary' format provides outputs the results of one test
        per line with the test's overall status (OK, SKIPPED, or
        FAILED).

        The 'junit' format is primarily intended for use with CI
        systems. It provides an XML representation of test
        status. Similar to the text format, it includes detailed
        information about test failures. Since many JUnit parser make
        assume that test names look like Java packet strings, the
        JUnit formatter automatically to something the looks like a
        Java class path ('.'->'-', '/'->'.').

        The 'pickle' format stores the raw results in a format that
        can be reformatted using this command. It's typically used
        with the show command to merge multiple test results into one
        pickle file.""")

    _add_format_args(parser)

    parser.add_argument("result", type=argparse.FileType("rb"), nargs="*",
                        help="Pickled test results")

def _show(args):
    def _load(f):
        # Load the pickled status file, sometimes e.g., when a
        # regression is still running the status file might be
        # incomplete.
        try:
            return pickle.load(f)
        except EOFError:
            print >> sys.stderr, 'Could not read file %s' % f.name
            return []

    formatter = _create_formatter(args)
    suites = sum([ _load(f) for f in args.result ], [])
    formatter.dump_suites(suites)

def _test_args(subparsers):
    parser = subparsers.add_parser(
        "test",
        formatter_class=ParagraphHelpFormatter,
        help='Probe test results and set exit code',
        epilog="""

        Load one or more pickled test file and return an exit code
        corresponding to the test outcome. The following exit codes
        can be returned:

        0: All tests were successful or skipped.

        1: General fault in the script such as incorrect parameters or
        failing to parse a pickle file.

        2: At least one test failed to run. This is what the summary
        formatter usually shows as a 'FAILED'.

        3: All tests ran correctly, but at least one failed to
        verify its output. When displaying test output using the
        summary formatter, such a test would show up as 'CHANGED'.
        """)

    parser.add_argument("result", type=argparse.FileType("rb"), nargs="*",
                        help="Pickled test results")

def _test(args):
    try:
        suites = sum([ pickle.load(f) for f in args.result ], [])
    except EOFError:
        print >> sys.stderr, 'Could not read all files'
        sys.exit(2)

    if all(s for s in suites):
        sys.exit(0)
    elif any([ s.failed_run() for s in suites ]):
        sys.exit(2)
    elif any([ s.changed() for s in suites ]):
        sys.exit(3)
    else:
        assert False, "Unexpected return status from test"

_commands = {
    "list" : (_list_tests, _list_tests_args),
    "run" : (_run_tests, _run_tests_args),
    "show" : (_show, _show_args),
    "test" : (_test, _test_args),
}

def main():
    parser = argparse.ArgumentParser(
        formatter_class=ParagraphHelpFormatter,
        description="""gem5 testing multi tool.""",
        epilog="""
        This tool provides an interface to gem5's test framework that
        doesn't depend on gem5's build system. It supports test
        listing, running, and output formatting.

        The list sub-command (e.g., "test.py list arm/quick") produces
        a list of tests tuples that can be used by the run command
        (e.g., "tests.py run gem5.opt
        quick/se/00.hello/arm/linux/simple-timing").

        The run command supports several output formats. One of them,
        pickle, contains the raw output from the tests and can be
        re-formatted using the show command (e.g., "tests.py show
        --format summary *.pickle"). Such pickle files are also
        generated by the build system when scons is used to run
        regressions.

        See the usage strings for the individual sub-commands for
        details.""")

    parser.add_argument("--verbose", action="store_true",
                        help="Produce more verbose output")

    subparsers = parser.add_subparsers(dest="command")

    for key, (impl, cmd_parser) in _commands.items():
        cmd_parser(subparsers)

    args = parser.parse_args()
    impl, cmd_parser = _commands[args.command]
    impl(args)

if __name__ == "__main__":
    main()
