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

#FIXME: Remove before release
if env['internal_only']:
    SConscript('./validation_old/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)
]

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

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

# Add unit tests
files_validation += Glob('validation/UNIT/*.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')

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

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

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

if env['neon']:
    files_benchmark += Glob('benchmark/NEON/*/*.cpp')
    files_benchmark += Glob('benchmark/NEON/*.cpp')

    files_validation += Glob('validation/NEON/*/*.cpp')
    files_validation += Glob('validation/NEON/*.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)

    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)

    Default(arm_compute_validation)
    Export('arm_compute_validation')
