# Copyright 2018 Google, Inc.
#
# 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.

Import('*')

if env['CONF']['USE_SYSTEMC'] and GetOption('with_systemc_tests'):

    from gem5_scons import Transform

    import os
    import os.path
    import json

    src = str(Dir('.').srcdir)

    class SystemCTest(object):
        def __init__(self, dirname, name):
            self.name = name
            self.reldir = os.path.relpath(dirname, src)
            self.target = os.path.join(self.reldir, name)
            self.sources = []
            self.deps = []

            self.compile_only = False

        def add_source(self, source):
            self.sources.append(os.path.join(self.reldir, source))

        def add_sources(self, sources):
            for source in sources:
                self.sources.append(os.path.join(self.reldir, '..', source))

        def properties(self):
            return {
                'name' : self.name,
                'path' : self.reldir,
                'compile_only' : self.compile_only,
                'deps' : self.deps
            }

    test_dir = Dir('.')
    class SystemCTestBin(Executable):
        def __init__(self, test):
            all_sources = test.sources + [with_tag('main')]
            super().__init__(test.target, *all_sources)
            self.reldir = test.reldir
            self.test_deps = test.deps

        @classmethod
        def declare_all(cls, env):
            env = env.Clone()

            # Turn off extra warnings and Werror for the tests.
            to_remove = ['-Wall', '-Wundef', '-Wextra', '-Werror']
            env['CCFLAGS'] = \
                list(filter(lambda f: f not in to_remove, env['CCFLAGS']))

            env.Append(CPPPATH=test_dir.Dir('include'))

            env.Append(LIBPATH=['${BUILDDIR}'], LIBS=['gem5_${ENV_LABEL}'])
            env.AddLocalRPATH('${BUILDDIR}')

            env['OBJSUFFIX'] = '.sc' + env['OBJSUFFIX'][1:]
            env['SHOBJSUFFIX'] = '.sc' + env['OBJSUFFIX'][1:]

            super().declare_all(env)

        def declare(self, env):
            test_bin, _u = super().declare(env)
            test_dir = self.dir.Dir(self.reldir)
            for dep in self.test_deps:
                env.Depends(test_bin, test_dir.File(dep))
            return test_bin

    tests = []
    def new_test(dirname, name):
        test = SystemCTest(dirname, name)
        tests.append(test)
        return test


    def scan_dir_for_tests(subdir):
        subdir_src = Dir('.').srcdir.Dir(subdir)
        for root, dirs, files in os.walk(str(subdir_src)):
            # If there's a 'DONTRUN' file in this directory, skip it and any
            # child directories.
            if 'DONTRUN' in files:
                del dirs[:]
                return

            endswith = lambda sfx: list(filter(
                        lambda n: n.endswith(sfx), files))

            cpps = endswith('.cpp')
            if not cpps:
                continue

            def get_entries(fname):
                with open(os.path.join(root, fname)) as content:
                    lines = content.readlines
                    # Get rid of leading and trailing whitespace.
                    lines = map(lambda x: x.strip(), content.readlines())
                    # Get rid of blank lines.
                    lines = list(filter(lambda x: x, lines))
                    return lines

            # If there's only one source file, then that files name is the test
            # name, and it's the source for that test.
            if len(cpps) == 1:
                cpp = cpps[0]

                test = new_test(root, os.path.splitext(cpp)[0])
                test.add_source(cpp)

            # Otherwise, expect there to be a file that ends in .f. That files
            # name is the test name, and it will list the source files with
            # one preceeding path component.
            else:
                fs = endswith('.f')
                if len(fs) != 1:
                    print("In %s, expected 1 *.f file, but found %d.",
                          root, len(fs))
                    for f in fs:
                        print(os.path.join(root, f))
                    return
                f = fs[0]

                test = new_test(root, os.path.splitext(f)[0])
                # Add all the sources to this test.
                test.add_sources(get_entries(f))

            if 'COMPILE' in files:
                test.compile_only = True

            if 'DEPS' in files:
                test.deps = get_entries('DEPS')

    scan_dir_for_tests('systemc')
    scan_dir_for_tests('tlm')


    def build_tests_json(target, source, env):
        data = { test.target : test.properties() for test in tests }
        with open(str(target[0]), "w") as tests_json:
            json.dump(data, tests_json)

    AlwaysBuild(env.Command(File('tests.json'), None,
                MakeAction(build_tests_json, Transform("TESTJSON"))))


    for test in tests:
        SystemCTestBin(test)
