# 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 (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 env['os'] in ['android', 'bare_metal'] or env['standalone']:
    Import('arm_compute_a')
    old_validation_env.Append(LIBS = [arm_compute_a])
    arm_compute_lib = arm_compute_a
else:
    Import('arm_compute_so')
    old_validation_env.Append(LIBS = ["arm_compute"])
    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 = [".", "#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')
old_files_validation = [f for f in old_files_validation if "main.cpp" not in os.path.basename(str(f))]
old_files_validation += Glob('validation/*.cpp')

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

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

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

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

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

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

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

#######################################################################
# Using new framework
#######################################################################

# Clone the environment to make sure we're not polluting the arm_compute one:
test_env = env.Clone()
# Workaround to build both test systems in parallel
test_env.VariantDir("new", ".", duplicate=0)

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

#FIXME Delete before release
if old_validation_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/framework" % 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('new/AssetsLibrary.cpp')
common_files += Glob('new/RawTensor.cpp')
common_files += Glob('new/main.cpp')

common_objects = [test_env.StaticObject(f) for f in common_files]

files_benchmark = Glob('new/benchmark_new/*.cpp')
files_validation = Glob('new/validation_new/*.cpp')

# Always compile reference for validation
files_validation += Glob('new/validation_new/CPP/*.cpp')

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

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

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

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

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

    files_validation += Glob('new/validation_new/NEON/*/*.cpp')
    files_validation += Glob('new/validation_new/NEON/*.cpp')

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

if old_validation_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 old_validation_env['validation_tests']:
    arm_compute_validation_new = test_env.Program('arm_compute_validation_new', files_validation + common_objects)
    Depends(arm_compute_validation_new, arm_compute_test_framework)
    Depends(arm_compute_validation_new, arm_compute_lib)

    if env['opencl']:
        Depends(arm_compute_validation_new, opencl)

    Default(arm_compute_validation_new)
    Export('arm_compute_validation_new')
