# 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:
common_env = env.Clone()
vars.Update(common_env)

Help(new_options.GenerateHelpText(common_env))

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

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

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

validation_env = common_env.Clone()

validation_env.Append(CPPDEFINES=['BOOST'])

files = Glob('*.cpp')
files = [f for f in files if "DatasetManager" not in os.path.basename(str(f))]

common_objects = [ common_env.StaticObject( f ) for f in files ]

validation_env.Append(LIBS = ['boost_unit_test_framework'])

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

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

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

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

    validation_env.Append(LIBS = "OpenCL")

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

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

if common_env['validation_tests']:
    arm_compute_validation = validation_env.Program('arm_compute_validation',
                                                   files_validation + common_objects)
    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:
benchmark_env = env.Clone()
# Workaround to build both test systems in parallel
benchmark_env.VariantDir("new", ".", duplicate=0)

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

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

benchmark_env.Append(CPPPATH = [".", "#3rdparty/include"])
benchmark_env.Append(LIBPATH = ["#3rdparty/%s/%s" % (env['os'], env['arch'])])
benchmark_env.Append(LIBPATH = ["#build/%s" % env['build_dir']])
benchmark_env.Append(LIBPATH = ["#build/%s/framework" % env['build_dir']])
benchmark_env.Append(LIBPATH = ["#build/%s/opencl-1.2-stubs" % env['build_dir']])

Import("arm_compute_test_framework")
benchmark_env.Append(LIBS = ['arm_compute_test_framework'])

files_benchmark = Glob('new/DatasetManager.cpp')
files_benchmark += Glob('new/TensorLibrary.cpp')
files_benchmark += Glob('new/RawTensor.cpp')
files_benchmark += Glob('new/benchmark_new/*.cpp')

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

    benchmark_env.Append(CPPDEFINES=['ARM_COMPUTE_CL'])

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

    benchmark_env.Append(LIBS = "OpenCL")

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

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

if common_env['benchmark_tests']:
    arm_compute_benchmark = benchmark_env.Program('arm_compute_benchmark', files_benchmark)
    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')
