# 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 ['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/CPP/*.cpp')

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

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