# 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')
    class SystemCTestBin(UnitTest):
        def __init__(self, test):
            super(SystemCTestBin, self).__init__(
                    test.target, *test.sources, main=True)

        @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=ext_dir)

            super(SystemCTestBin, cls).declare_all(env)

    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)
