#!/usr/bin/env python2
#
# Copyright (c) 2016-2017 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

from abc import ABCMeta, abstractmethod
import os
from collections import namedtuple
from units import *
from results import TestResult
import shutil

_test_base = os.path.join(os.path.dirname(__file__), "..")

ClassicConfig = namedtuple("ClassicConfig", (
    "category",
    "mode",
    "workload",
    "isa",
    "os",
    "config",
))

# There are currently two "classes" of test
# configurations. Architecture-specific ones and generic ones
# (typically SE mode tests). In both cases, the configuration name
# matches a file in tests/configs/ that will be picked up by the test
# runner (run.py).
#
# Architecture specific configurations are listed in the arch_configs
# dictionary. This is indexed by a (cpu architecture, gpu
# architecture) tuple. GPU architecture is optional and may be None.
#
# Generic configurations are listed in the generic_configs tuple.
#
# When discovering available test cases, this script look uses the
# test list as a list of /candidate/ configurations. A configuration
# is only used if a test has a reference output for that
# configuration. In addition to the base configurations from
# arch_configs and generic_configs, a Ruby configuration may be
# appended to the base name (this is probed /in addition/ to the
# original name. See get_tests() for details.
#
arch_configs = {
    ("alpha", None) : (
        'tsunami-simple-atomic',
        'tsunami-simple-timing',
        'tsunami-simple-atomic-dual',
        'tsunami-simple-timing-dual',
        'twosys-tsunami-simple-atomic',
        'tsunami-o3', 'tsunami-o3-dual',
        'tsunami-minor', 'tsunami-minor-dual',
        'tsunami-switcheroo-full',
    ),

    ("arm", None) : (
        'simple-atomic-dummychecker',
        'o3-timing-checker',
        'realview-simple-atomic',
        'realview-simple-atomic-dual',
        'realview-simple-atomic-checkpoint',
        'realview-simple-timing',
        'realview-simple-timing-dual',
        'realview-o3',
        'realview-o3-checker',
        'realview-o3-dual',
        'realview-minor',
        'realview-minor-dual',
        'realview-switcheroo-atomic',
        'realview-switcheroo-timing',
        'realview-switcheroo-noncaching-timing',
        'realview-switcheroo-o3',
        'realview-switcheroo-full',
        'realview64-simple-atomic',
        'realview64-simple-atomic-checkpoint',
        'realview64-simple-atomic-dual',
        'realview64-simple-timing',
        'realview64-simple-timing-dual',
        'realview64-o3',
        'realview64-o3-checker',
        'realview64-o3-dual',
        'realview64-minor',
        'realview64-minor-dual',
        'realview64-switcheroo-atomic',
        'realview64-switcheroo-timing',
        'realview64-switcheroo-o3',
        'realview64-switcheroo-full',
    ),

    ("sparc", None) : (
        't1000-simple-atomic',
        't1000-simple-x86',
    ),

    ("timing", None) : (
        'pc-simple-atomic',
        'pc-simple-timing',
        'pc-o3-timing',
        'pc-switcheroo-full',
    ),

    ("x86", "hsail") : (
        'gpu',
    ),
}

generic_configs = (
    'simple-atomic',
    'simple-atomic-mp',
    'simple-timing',
    'simple-timing-mp',

    'minor-timing',
    'minor-timing-mp',

    'o3-timing',
    'o3-timing-mt',
    'o3-timing-mp',

    'rubytest',
    'memcheck',
    'memtest',
    'memtest-filter',
    'tgen-simple-mem',
    'tgen-dram-ctrl',
    'dram-lowp',

    'learning-gem5-p1-simple',
    'learning-gem5-p1-two-level',
)

default_ruby_protocol = {
    "arm" : "MOESI_CMP_directory",
}

def get_default_protocol(arch):
    return default_ruby_protocol.get(arch, 'MI_example')

all_categories = ("quick", "long")
all_modes = ("fs", "se")

class Test(object):
    """Test case base class.

    Test cases consists of one or more test units that are run in two
    phases. A run phase (units produced by run_units() and a verify
    phase (units from verify_units()). The verify phase is skipped if
    the run phase fails.

    """

    __metaclass__ = ABCMeta

    def __init__(self, name):
        self.test_name = name

    @abstractmethod
    def ref_files(self):
        """Get a list of reference files used by this test case"""
        pass

    @abstractmethod
    def run_units(self):
        """Units (typically RunGem5 instances) that describe the run phase of
        this test.

        """
        pass

    @abstractmethod
    def verify_units(self):
        """Verify the output from the run phase (see run_units())."""
        pass

    @abstractmethod
    def update_ref(self):
        """Update reference files with files from a test run"""
        pass

    def run(self):
        """Run this test case and return a list of results"""

        run_results = [ u.run() for u in self.run_units() ]
        run_ok = all([not r.skipped() and r for r in run_results ])

        verify_results = [
            u.run() if run_ok else u.skip()
            for u in self.verify_units()
        ]

        return TestResult(self.test_name,
                          run_results=run_results,
                          verify_results=verify_results)

    def __str__(self):
        return self.test_name

class ClassicTest(Test):
    # The diff ignore list contains all files that shouldn't be diffed
    # using DiffOutFile. These files typically use special-purpose
    # diff tools (e.g., DiffStatFile).
    diff_ignore_files = FileIgnoreList(
        names=(
            # Stat files use a special stat differ
            "stats.txt",
        ), rex=(
        ))

    # These files should never be included in the list of
    # reference files. This list should include temporary files
    # and other files that we don't care about.
    ref_ignore_files = FileIgnoreList(
        names=(
            "EMPTY",
        ), rex=(
            # Mercurial sometimes leaves backups when applying MQ patches
            r"\.orig$",
            r"\.rej$",
        ))

    def __init__(self, gem5, output_dir, config_tuple,
                 timeout=None,
                 skip=False, skip_diff_out=False, skip_diff_stat=False):

        super(ClassicTest, self).__init__("/".join(config_tuple))

        ct = config_tuple

        self.gem5 = os.path.abspath(gem5)
        self.script = os.path.join(_test_base, "run.py")
        self.config_tuple = ct
        self.timeout = timeout

        self.output_dir = output_dir
        self.ref_dir = os.path.join(_test_base,
                                    ct.category, ct.mode, ct.workload,
                                    "ref", ct.isa, ct.os, ct.config)
        self.skip_run = skip
        self.skip_diff_out = skip or skip_diff_out
        self.skip_diff_stat = skip or skip_diff_stat

    def ref_files(self):
        ref_dir = os.path.abspath(self.ref_dir)
        for root, dirs, files in os.walk(ref_dir, topdown=False):
            for f in files:
                fpath = os.path.join(root[len(ref_dir) + 1:], f)
                if fpath not in ClassicTest.ref_ignore_files:
                    yield fpath

    def run_units(self):
        args = [
            self.script,
            "/".join(self.config_tuple),
        ]

        return [
            RunGem5(self.gem5, args,
                    ref_dir=self.ref_dir, test_dir=self.output_dir,
                    skip=self.skip_run),
        ]

    def verify_units(self):
        ref_files = set(self.ref_files())
        units = []
        if "stats.txt" in ref_files:
            units.append(
                DiffStatFile(ref_dir=self.ref_dir, test_dir=self.output_dir,
                             skip=self.skip_diff_stat))
        units += [
            DiffOutFile(f,
                        ref_dir=self.ref_dir, test_dir=self.output_dir,
                        skip=self.skip_diff_out)
            for f in ref_files if f not in ClassicTest.diff_ignore_files
        ]

        return units

    def update_ref(self):
        for fname in self.ref_files():
            shutil.copy(
                os.path.join(self.output_dir, fname),
                os.path.join(self.ref_dir, fname))

def parse_test_filter(test_filter):
    wildcards = ("", "*")

    _filter = list(test_filter.split("/"))
    if len(_filter) > 3:
        raise RuntimeError("Illegal test filter string")
    _filter += [ "", ] * (3 - len(_filter))

    isa, cat, mode = _filter

    if isa in wildcards:
        raise RuntimeError("No ISA specified")

    cat = all_categories if cat in wildcards else (cat, )
    mode = all_modes if mode in wildcards else (mode, )

    return isa, cat, mode

def get_tests(isa,
              categories=all_categories, modes=all_modes,
              ruby_protocol=None, gpu_isa=None):

    # Generate a list of candidate configs
    configs = list(arch_configs.get((isa, gpu_isa), []))

    if (isa, gpu_isa) == ("x86", "hsail"):
        if ruby_protocol == "GPU_RfO":
            configs += ['gpu-randomtest']
    else:
        configs += generic_configs

    if ruby_protocol == get_default_protocol(isa):
        if ruby_protocol == 'MI_example':
            configs += [ "%s-ruby" % (c, ) for c in configs ]
        else:
            configs += [ "%s-ruby-%s" % (c, ruby_protocol) for c in configs ]
    elif ruby_protocol is not None:
        # Override generic ISA configs when using Ruby (excluding
        # MI_example which is included in all ISAs by default). This
        # reduces the number of generic tests we re-run for when
        # compiling Ruby targets.
        configs = [ "%s-ruby-%s" % (c, ruby_protocol) for c in configs ]

    # /(quick|long)/(fs|se)/workload/ref/arch/guest/config/
    for conf_script in configs:
        for cat in categories:
            for mode in modes:
                mode_dir = os.path.join(_test_base, cat, mode)
                if not os.path.exists(mode_dir):
                    continue

                for workload in os.listdir(mode_dir):
                    isa_dir = os.path.join(mode_dir, workload, "ref", isa)
                    if not os.path.isdir(isa_dir):
                        continue

                    for _os in os.listdir(isa_dir):
                        test_dir = os.path.join(isa_dir, _os, conf_script)
                        if not os.path.exists(test_dir) or \
                           os.path.exists(os.path.join(test_dir, "skip")):
                            continue

                        yield ClassicConfig(cat, mode, workload, isa, _os,
                                            conf_script)
