# 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.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
            }

    ext_dir = Dir('..').Dir('ext')
    test_dir = Dir('.')
    class SystemCTestBin(Executable):
        def __init__(self, test):
            super(SystemCTestBin, self).__init__(test.target, *test.sources)

        @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'))
            env.Append(CPPPATH=ext_dir)

            super(SystemCTestBin, cls).declare_all(env)

        def declare(self, env):
            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['SHARED_LIB'] + env['MAIN_OBJS']
            return super(SystemCTestBin, self).declare(env, objs)

    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

            # 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])
                with open(os.path.join(dirname, f)) 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)
                    # Add all the sources to this test.
                    test.add_sources(lines)

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

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

    scan_dir_for_tests('systemc')


    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)
