# 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.
#
# Authors: Gabe Black

from __future__ import print_function

Import('*')

if env['USE_SYSTEMC']:

    from gem5_scons import Transform

    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):
            super(SystemCTestBin, self).__init__(test.target, *test.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'] = \
                filter(lambda f: f not in to_remove, env['CCFLAGS'])

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

            shared_lib_path = env['SHARED_LIB'][0].abspath
            sl_dir, sl_base = os.path.split(shared_lib_path)
            env.Append(LIBPATH=[sl_dir], LIBS=[sl_base])

            super(SystemCTestBin, cls).declare_all(env)

        def declare(self, env):
            env = env.Clone()
            sources = list(self.sources)
            for f in self.filters:
                sources = Source.all.apply_filter(f)
            objs = self.srcs_to_objs(env, sources)
            objs = objs + env['MAIN_OBJS']
            relpath = os.path.relpath(
                    env['SHARED_LIB'][0].dir.abspath,
                    self.path(env).dir.abspath)
            env.Append(LINKFLAGS=Split('-z origin'))
            env.Append(RPATH=[
                    env.Literal(os.path.join('\\$$ORIGIN', relpath))])
            test_bin = super(SystemCTestBin, self).declare(env, objs)
            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):
        def visitor(arg, dirname, names):
            # If there's a 'DONTRUN' file in this directory, skip it and any
            # child directories.
            if 'DONTRUN' in names:
                del names[:]
                return

            endswith = lambda sfx: filter(lambda n: n.endswith(sfx), names)

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

            def get_entries(fname):
                with open(os.path.join(dirname, 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 = 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(dirname, 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.",
                          dirname, len(fs))
                    for f in fs:
                        print(os.path.join(dirname, f))
                    return
                f = fs[0]

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

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

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

        subdir_src = Dir('.').srcdir.Dir(subdir)
        os.path.walk(str(subdir_src), visitor, None)

    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)
