# 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)
