# Copyright (c) 2017, 2018 ARM Limited.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import SCons
import os.path

Import('env')
Import('vars')

SConscript('./framework/SConscript', duplicate=0)

# vars is imported from arm_compute:
variables = [
    #FIXME: Remove before release!
    BoolVariable("benchmark_examples", "Build benchmark examples programs", True),
    BoolVariable("validate_examples", "Build benchmark examples programs", True),
    #FIXME Switch the following two options to False before releasing
    BoolVariable("validation_tests", "Build validation test programs", True),
    BoolVariable("benchmark_tests", "Build benchmark test programs", True),
    ("test_filter", "Pattern to specify the tests' filenames to be compiled", "*.cpp")
]

# We need a separate set of Variables for the Help message (Otherwise the global variables will get displayed twice)
new_options = Variables('scons')

for v in variables:
    new_options.Add(v)
    vars.Add(v)

# Disable floating-point expression contraction (e.g. fused multiply-add operations)
env.Append(CXXFLAGS = ['-ffp-contract=off'])

# Clone the environment to make sure we're not polluting the arm_compute one:
test_env = env.Clone()
vars.Update(test_env)

Help(new_options.GenerateHelpText(test_env))

Import("arm_compute_test_framework")
test_env.Append(LIBS = arm_compute_test_framework)

if env['os'] in ['android', 'bare_metal'] or env['standalone']:
    Import("arm_compute_a")
    Import("arm_compute_core_a")
    test_env.Append(LIBS = [arm_compute_a, arm_compute_core_a])
    arm_compute_lib = arm_compute_a
else:
    Import("arm_compute_so")
    test_env.Append(LIBS = ["arm_compute", "arm_compute_core"])
    arm_compute_lib = arm_compute_so

#FIXME Delete before release
if env['internal_only']:
    test_env.Append(CPPDEFINES=['INTERNAL_ONLY'])

test_env.Append(CPPPATH = ["#3rdparty/include"])
test_env.Append(LIBPATH = ["#3rdparty/%s/%s" % (env['os'], env['arch'])])
test_env.Append(LIBPATH = ["#build/%s" % env['build_dir']])

common_files = Glob('*.cpp')
common_objects = [test_env.StaticObject(f) for f in common_files]

files_benchmark = Glob('benchmark/*.cpp')
files_validation_framework = [test_env.Object(f) for f in Glob('validation/*.cpp')]

# Always compile reference for validation
files_validation_framework += [ test_env.Object(f) for f in Glob('validation/reference/*.cpp')]

# Add unit tests
files_validation = Glob('validation/UNIT/*/*.cpp')
files_validation += Glob('validation/UNIT/*.cpp')

# Add CPP tests
filter_pattern = test_env['test_filter']
files_validation += Glob('validation/CPP/' + filter_pattern)

if env['opencl']:
    filter_pattern = test_env['test_filter']

    test_env.Append(CPPDEFINES=['ARM_COMPUTE_CL'])

    files_benchmark += Glob('benchmark/CL/*/' + filter_pattern)
    files_benchmark += Glob('benchmark/CL/' + filter_pattern)

    files_validation += Glob('validation/CL/*/' + filter_pattern)
    files_validation += Glob('validation/CL/' + filter_pattern)

if env['neon']:
    filter_pattern = test_env['test_filter']
    files_benchmark += Glob('benchmark/NEON/*/' + filter_pattern)
    files_benchmark += Glob('benchmark/NEON/' + filter_pattern)

    files_validation += Glob('validation/NEON/*/' + filter_pattern)
    files_validation += Glob('validation/NEON/' + filter_pattern)

if env['gles_compute']:
    test_env.Append(CPPDEFINES=['ARM_COMPUTE_GC'])

    files_benchmark += Glob('benchmark/GLES_COMPUTE/*/*.cpp')
    files_benchmark += Glob('benchmark/GLES_COMPUTE/*.cpp')

    files_validation += Glob('validation/GLES_COMPUTE/*/*.cpp')
    files_validation += Glob('validation/GLES_COMPUTE/*.cpp')

if env['os'] == 'android':
    test_env.Append(LIBS = ["log"])
else:
    test_env.Append(LIBS = ["rt"])

if test_env['benchmark_tests']:
    arm_compute_benchmark = test_env.Program('arm_compute_benchmark', files_benchmark + common_objects)
    Depends(arm_compute_benchmark, arm_compute_test_framework)
    Depends(arm_compute_benchmark, arm_compute_lib)
    Default(arm_compute_benchmark)
    Export('arm_compute_benchmark')

if test_env['validation_tests']:
    arm_compute_validation = test_env.Program('arm_compute_validation', files_validation_framework + files_validation + common_objects)
    Depends(arm_compute_validation, arm_compute_test_framework)
    Depends(arm_compute_validation, arm_compute_lib)

    Default(arm_compute_validation)
    Export('arm_compute_validation')

    #FIXME: Remove before release!
    if test_env['validate_examples']:
        files_validate_examples = [ test_env.Object('validate_examples/RunExample.cpp') ] + files_validation_framework + [ x for x in common_objects if not "main.o" in str(x)]
        arm_compute_validate_examples = []
        if test_env['neon']:
            for file in Glob("validate_examples/neon_*.cpp"):
                example = "validate_" + os.path.basename(os.path.splitext(str(file))[0])
                arm_compute_validate_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_validate_examples) ]
        if test_env['opencl']:
            cl_examples = []
            files = Glob("validate_examples/cl_*.cpp")
            if test_env['neon']:
                files += Glob("validate_examples/neoncl_*.cpp")
            for file in files:
                example = "validate_" + os.path.basename(os.path.splitext(str(file))[0])
                cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_validate_examples, LIBS = test_env["LIBS"]) ]
            arm_compute_validate_examples += cl_examples
            if test_env['opencl'] and test_env['neon']:
                if env['os'] == 'android':
                    Import('arm_compute_graph_a')
                    graph_dependency = [ arm_compute_graph_a]
                else:
                    Import('arm_compute_graph_so')
                    graph_dependency = [ arm_compute_graph_so]

                graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils")
                for file in Glob("validate_examples/graph_*.cpp"):
                    example = "validate_" + os.path.basename(os.path.splitext(str(file))[0])
                    if env['os'] == 'android':
                        prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive'])
                        Depends(prog, graph_dependency)
                        arm_compute_validate_examples += [ prog ]
                    else:
                        #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies
                        prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] )
                        Depends(prog, graph_dependency)
                        arm_compute_validate_examples += [ prog ]
        Depends(arm_compute_validate_examples, arm_compute_test_framework)
        Depends(arm_compute_validate_examples, arm_compute_lib)
        Default(arm_compute_validate_examples)
        Export('arm_compute_validate_examples')

#FIXME: Remove before release!
if test_env['benchmark_examples']:
    files_benchmark_examples = test_env.Object('benchmark_examples/RunExample.cpp')
    arm_compute_benchmark_examples = []
    if test_env['neon']:
        for file in Glob("../examples/neon_*.cpp"):
            example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0])
            arm_compute_benchmark_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_benchmark_examples) ]
    if test_env['opencl']:
        cl_examples = []
        files = Glob("../examples/cl_*.cpp")
        if test_env['neon']:
            files += Glob("../examples/neoncl_*.cpp")
        for file in files:
            example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0])
            cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_benchmark_examples, LIBS = test_env["LIBS"]) ]
        arm_compute_benchmark_examples += cl_examples

    # Graph examples
    if env['os'] == 'android':
        Import('arm_compute_graph_a')
        graph_dependency = [arm_compute_graph_a]
    else:
        Import('arm_compute_graph_so')
        graph_dependency = [arm_compute_graph_so]
    graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils")
    for file in Glob("../examples/graph_*.cpp"):
        example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0])
        if env['os'] == 'android':
            prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive'])
            Depends(prog, [graph_dependency])
            arm_compute_benchmark_examples += [ prog ]
        else:
            #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies
            prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] )
            Depends(prog, graph_dependency)
            arm_compute_benchmark_examples += [ prog ]
    Depends(arm_compute_benchmark_examples, arm_compute_test_framework)
    Depends(arm_compute_benchmark_examples, arm_compute_lib)
    Default(arm_compute_benchmark_examples)
    Export('arm_compute_benchmark_examples')

