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

# vars is imported from arm_compute:
variables = [
    #FIXME: Remove before release!
    BoolVariable("openvx", "Enable OpenVX support in tests", False),
    BoolVariable("openblas", "Enable OpenBLAS support in tests", False),
    #FIXME Remove before release (And remove all references to INTERNAL_ONLY)
    BoolVariable("internal_only", "Enable ARM internal only tests", True),
    BoolVariable("pmu", "Enable PMU counters", False),
    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)

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

Help(new_options.GenerateHelpText(old_validation_env))

if old_validation_env['openblas']:
    if env['os'] == 'bare_metal':
        print("OpenBLAS is not supported on bare metal")
        Exit(1)
    old_validation_env.Append(CPPDEFINES = ['USE_OPENBLAS'])
    old_validation_env.Append(LIBS = ['openblas', 'pthread'])

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

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

old_validation_env.Append(CPPPATH = [".", "#tests", "#3rdparty/include"])
old_validation_env.Append(LIBPATH = ["#3rdparty/%s/%s" % (env['os'], env['arch'])])
old_validation_env.Append(LIBPATH = ["#build/%s" % env['build_dir']])
old_validation_env.Append(LIBPATH = ["#build/%s/opencl-1.2-stubs" % env['build_dir']])
old_validation_env.Append(LIBS = ['boost_program_options'])
old_validation_env.Append(CXXFLAGS = ['-Wno-missing-field-initializers'])
old_validation_env.Append(CPPDEFINES=['BOOST'])
old_validation_env.Append(LIBS = ['boost_unit_test_framework'])

old_files_validation = Glob('*.cpp')

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

if env['opencl']:
    Import('opencl')

    old_files_validation += Glob('CL/*.cpp')
    old_files_validation += Glob('CL/*/*.cpp')
    old_files_validation += Glob('system_tests/CL/*.cpp')

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

#FIXME Remove before release
if old_validation_env['openvx']:
    old_files_validation += Glob('VX/*.cpp')
    old_files_validation += Glob('VX/*/*.cpp')

    old_validation_env.Append(LIBS = ['openvx', 'vxu'])

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

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

if old_validation_env['validation_tests']:
    arm_compute_validation_old = old_validation_env.Program('arm_compute_validation_old', old_files_validation)
    Depends(arm_compute_validation_old, arm_compute_lib)
    if env['opencl']:
        Depends(arm_compute_validation_old, opencl)
    Default(arm_compute_validation_old)
    Export('arm_compute_validation_old')
