# Copyright (c) 2017 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 = [
    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))

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']])
test_env.Append(LIBPATH = ["#build/%s/opencl-1.2-stubs" % env['build_dir']])
if env['gles_compute'] and env['os'] != 'android':
    test_env.Append(LIBPATH = ["#build/%s/opengles-3.1/stubs" % env['build_dir']])

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

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

files_benchmark = Glob('benchmark/*.cpp')
files_validation = Glob('validation/*.cpp')

# Always compile reference for validation
files_validation += 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']:
    Import('opencl')
    filter_pattern = test_env['test_filter']

    test_env.Append(CPPDEFINES=['ARM_COMPUTE_CL'])
    test_env.Append(LIBS = ["OpenCL"])

    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']:
    if env['os'] != 'android':
        Import('egl')
        Import('glesv2')

        test_env.Append(CPPPATH = ["#opengles-3.1/include", "#opengles-3.1/mali_include"])
        test_env.Append(LIBS = ["EGL", "GLESv2"])
    else:
        if env['arch'] != 'armv7a':
            test_env.Append(LIBS = ["EGL", "GLESv3"])
        else:
            test_env.Append(LIBS = ["EGL", "GLESv2"])

    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)

    if env['opencl']:
        Depends(arm_compute_benchmark, opencl)
    if env['gles_compute'] and env['os'] != 'android':
        Depends(arm_compute_benchmark, egl)
        Depends(arm_compute_benchmark, glesv2)

    Default(arm_compute_benchmark)
    Export('arm_compute_benchmark')

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

    if env['opencl']:
        Depends(arm_compute_validation, opencl)
    if env['gles_compute'] and env['os'] != 'android':
        Depends(arm_compute_validation, egl)
        Depends(arm_compute_validation, glesv2)

    Default(arm_compute_validation)
    Export('arm_compute_validation')
