# Copyright (c) 2017-2019 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')
Import('install_bin')

# vars is imported from arm_compute:
variables = [
    BoolVariable("benchmark_examples", "Build benchmark examples programs", True),
    BoolVariable("validate_examples", "Build validate 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)

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

# Check if we need to build the test framework
build_test_framework = False
for opt in new_options.keys():
    option_value = test_env[opt]
    if type(option_value) is bool and option_value:
        build_test_framework = True
        break

if not build_test_framework:
    Return()
else:
    SConscript('./framework/SConscript', duplicate=0)

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

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

# Remove -Wnoexcept from tests
if 'g++' in test_env['CXX'] and '-Wnoexcept' in test_env['CXXFLAGS']:
    test_env['CXXFLAGS'].remove("-Wnoexcept")

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

if env['os'] in ['bare_metal']:
    Import("bootcode_o")

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

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

files_benchmark = Glob('benchmark/*.cpp')
#FIXME Delete before release
if env['internal_only']:
    files_benchmark += Glob('../3rdparty/tests/benchmark/*.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)
    #FIXME Delete before release
    if env['internal_only']:
        files_benchmark += Glob('../3rdparty/tests/benchmark/CL/' + filter_pattern)

    files_validation += Glob('validation/CL/*/' + filter_pattern)
    files_validation += Glob('validation/CL/' + filter_pattern)
    #FIXME Delete before release
    if env['internal_only']:
        files_validation += Glob('../3rdparty/tests/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)
    #FIXME Delete before release
    if env['internal_only']:
        files_benchmark += Glob('../3rdparty/tests/benchmark/NEON/' + filter_pattern)

    files_validation += Glob('validation/NEON/' + filter_pattern)
    if env['os'] == 'bare_metal':
        files_validation += Glob('validation/NEON/UNIT/MemoryManager.cpp' + filter_pattern)
        files_validation += Glob('validation/NEON/UNIT/DynamicTensor.cpp' + filter_pattern)
        files_validation += Glob('validation/NEON/UNIT/TensorAllocator.cpp' + filter_pattern)
    else:
        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"])
elif env['os'] != 'bare_metal':
    test_env.Append(LIBS = ["rt"])

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

bm_link_flags = ['-fstack-protector-strong']
if test_env['linker_script']:
    bm_link_flags += ['-Wl,--build-id=none', '-T', env['linker_script']]

if test_env['validation_tests']:
    arm_compute_validation_framework = env.StaticLibrary('arm_compute_validation_framework', Glob('validation/reference/*.cpp') + Glob('validation/*.cpp'), LIBS= [ arm_compute_test_framework, arm_compute_core_a])
    Depends(arm_compute_validation_framework , arm_compute_test_framework)
    Depends(arm_compute_validation_framework , arm_compute_core_a)

    program_objects = files_validation + common_objects
    if test_env['os'] == 'bare_metal':
        Depends(arm_compute_validation_framework , bootcode_o)
        program_objects += bootcode_o


    arm_compute_validation = test_env.Program('arm_compute_validation', program_objects, LIBS=[arm_compute_validation_framework] + test_env['LIBS'], LINKFLAGS=test_env['LINKFLAGS'] + bm_link_flags)
    arm_compute_validation = install_bin(arm_compute_validation)
    Depends(arm_compute_validation, arm_compute_validation_framework)
    Depends(arm_compute_validation, arm_compute_test_framework)
    Depends(arm_compute_validation, arm_compute_lib)

    Default(arm_compute_validation)
    Export('arm_compute_validation')

    if test_env['validate_examples']:
        files_validate_examples = [ test_env.Object('validate_examples/RunExample.cpp') ] + [ x for x in common_objects if not "main.o" in str(x)]
        if test_env['os'] == 'bare_metal':
            files_validate_examples += bootcode_o

        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, LIBS = [ arm_compute_validation_framework], LINKFLAGS=test_env['LINKFLAGS'] + bm_link_flags) ]
        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_validation_framework ]) ]
            arm_compute_validate_examples += cl_examples
            if test_env['opencl'] and test_env['neon']:
                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'] in ['android', 'bare_metal'] or env['standalone']:
                        prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"] + [ arm_compute_validation_framework ], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',arm_compute_lib,'-Wl,--no-whole-archive'] + bm_link_flags)
                        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", arm_compute_validation_framework], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] )
                        arm_compute_validate_examples += [ prog ]
        arm_compute_validate_examples = install_bin(arm_compute_validate_examples)
        Depends(arm_compute_validate_examples, arm_compute_validation_framework)
        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')

if test_env['benchmark_examples']:
    files_benchmark_examples = test_env.Object('benchmark_examples/RunExample.cpp')
    if test_env['os'] == 'bare_metal':
        files_benchmark_examples += bootcode_o
    graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils")
    graph_params = test_env.Object(source="../utils/CommonGraphOptions.cpp", target="CommonGraphOptions")
    arm_compute_benchmark_examples = []
    for examples_folder in [ "../examples", "../3rdparty/examples"]:
        if test_env['neon']:
            for file in Glob("%s/neon_*.cpp" % examples_folder):
                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, LINKFLAGS=test_env["LINKFLAGS"]+ bm_link_flags) ]
        if test_env['opencl']:
            cl_examples = []
            files = Glob("%s/cl_*.cpp" % examples_folder)
            if test_env['neon']:
                files += Glob("%s/neoncl_*.cpp" % examples_folder)
            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

        if test_env['gemm_tuner'] and test_env['opencl']:
            gemm_tuner_examples = []
            gemm_tuner_common_options = test_env.Object(source="../examples/gemm_tuner/CommonGemmExampleOptions.cpp", target="CommonGemmExampleOptions")
            files = Glob("%s/gemm_tuner/cl_*.cpp" % examples_folder)
            for file in files:
                example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0])
                example = os.path.join("gemm_tuner", example)
                gemm_tuner_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example), gemm_tuner_common_options ] + files_benchmark_examples, LIBS = test_env["LIBS"]) ]
            arm_compute_benchmark_examples += gemm_tuner_examples

        # Graph examples
        for file in Glob("%s/graph_*.cpp" % examples_folder ):
            example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0])
            if env['os'] in ['android', 'bare_metal'] or env['standalone']:
                prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils, graph_params]+ files_benchmark_examples, LIBS = test_env["LIBS"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',arm_compute_lib,'-Wl,--no-whole-archive'] + bm_link_flags)
                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, graph_params]+ files_benchmark_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'])
                arm_compute_benchmark_examples += [ prog ]
    arm_compute_benchmark_examples = install_bin(arm_compute_benchmark_examples)
    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')
