# -*- Python -*-

import os
import platform
import re
import subprocess
import sys

import lit.formats
import lit.util

from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst

# Configuration file for the 'lit' test runner.

# name: The name of this test suite.
config.name = 'debuginfo-tests'

# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp', '.m']

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.join(config.debuginfo_tests_src_root)

# test_exec_root: The root path where tests should be run.
config.test_exec_root = config.debuginfo_tests_obj_root

llvm_config.use_default_substitutions()

tools = [
    ToolSubst('%test_debuginfo', command=os.path.join(
        config.debuginfo_tests_src_root, 'llgdb-tests', 'test_debuginfo.pl')),
    ToolSubst("%llvm_src_root", config.llvm_src_root),
    ToolSubst("%llvm_tools_dir", config.llvm_tools_dir),
]

def get_required_attr(config, attr_name):
  attr_value = getattr(config, attr_name, None)
  if attr_value == None:
    lit_config.fatal(
      "No attribute %r in test configuration! You may need to run "
      "tests from your build directory or add this attribute "
      "to lit.site.cfg " % attr_name)
  return attr_value

# If this is an MSVC environment, the tests at the root of the tree are
# unsupported. The local win_cdb test suite, however, is supported.
is_msvc = get_required_attr(config, "is_msvc")
if is_msvc:
    config.available_features.add('msvc')
    # FIXME: We should add some llvm lit utility code to find the Windows SDK
    # and set up the environment appopriately.
    win_sdk = 'C:/Program Files (x86)/Windows Kits/10/'
    arch = 'x64'
    llvm_config.with_system_environment(['LIB', 'LIBPATH', 'INCLUDE'])
    # Clear _NT_SYMBOL_PATH to prevent cdb from attempting to load symbols from
    # the network.
    llvm_config.with_environment('_NT_SYMBOL_PATH', '')
    tools.append(ToolSubst('%cdb', '"%s"' % os.path.join(win_sdk, 'Debuggers',
                                                         arch, 'cdb.exe')))

# clang_src_dir is not used by these tests, but is required by
# use_clang(), so set it to "".
if not hasattr(config, 'clang_src_dir'):
    config.clang_src_dir = ""
llvm_config.use_clang()

if config.llvm_use_sanitizer:
    # Propagate path to symbolizer for ASan/MSan.
    llvm_config.with_system_environment(
        ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH'])

def add_host_triple(clang):
  return '{} --target={}'.format(clang, config.host_triple)

# The set of arches we can build.
targets = set(config.targets_to_build)
# Add aliases to the target set.
if 'AArch64' in targets:
  targets.add('arm64')
if 'ARM' in config.targets_to_build:
  targets.add('thumbv7')

def can_target_host():
  # Check if the targets set contains anything that looks like our host arch.
  # The arch name in the triple and targets set may be spelled differently
  # (e.g. x86 vs X86).
  return any(config.host_triple.lower().startswith(x.lower())
             for x in targets)

# Dexter tests run on the host machine. If the host arch is supported add
# 'dexter' as an available feature and force the dexter tests to use the host
# triple.
if can_target_host():
  config.available_features.add('dexter')
  if config.host_triple != config.target_triple:
    print('Forcing dexter tests to use host triple {}.'.format(config.host_triple))
  llvm_config.with_environment('PATHTOCLANG',
                               add_host_triple(llvm_config.config.clang))
  llvm_config.with_environment('PATHTOCLANGPP',
                               add_host_triple(llvm_config.use_llvm_tool('clang++')))
  llvm_config.with_environment('PATHTOCLANGCL',
                               add_host_triple(llvm_config.use_llvm_tool('clang-cl')))
else:
  print('Host triple {} not supported. Skipping dexter tests in the '
        'debuginfo-tests project.'.format(config.host_triple))

# Check which debuggers are available:
built_lldb = llvm_config.use_llvm_tool('lldb', search_env='CLANG')
lldb_path = None
if built_lldb is not None:
    lldb_path = built_lldb
elif lit.util.which('lldb') is not None:
    lldb_path = lit.util.which('lldb')

if lldb_path is not None:
    config.available_features.add('lldb')

# Produce dexter path, lldb path, and combine into the %dexter substitution
# for running a test.
dexter_path = os.path.join(config.debuginfo_tests_src_root,
                           'dexter', 'dexter.py')
dexter_test_cmd = '"{}" "{}" test'.format(sys.executable, dexter_path)
if lldb_path is not None:
  dexter_test_cmd += ' --lldb-executable "{}"'.format(lldb_path)
tools.append(ToolSubst('%dexter', dexter_test_cmd))

# For testing other bits of dexter that aren't under the "test" subcommand,
# have a %dexter_base substitution.
dexter_base_cmd = '"{}" "{}"'.format(sys.executable, dexter_path)
tools.append(ToolSubst('%dexter_base', dexter_base_cmd))

# Set up commands for DexTer regression tests.
# Builder, debugger, optimisation level and several other flags differ
# depending on whether we're running a unix like or windows os.
if platform.system() == 'Windows': 
  dexter_regression_test_builder = '--builder clang-cl_vs2015'
  dexter_regression_test_debugger = '--debugger dbgeng'
  dexter_regression_test_cflags = '--cflags "/Zi /Od"'
  dexter_regression_test_ldflags = '--ldflags "/Zi"'
else:
  dexter_regression_test_builder = '--builder clang'
  dexter_regression_test_debugger = "--debugger lldb"
  dexter_regression_test_cflags = '--cflags "-O0 -glldb"'
  dexter_regression_test_ldflags = ''

# Typical command would take the form:
# ./path_to_py/python.exe ./path_to_dex/dexter.py test --fail-lt 1.0 -w --builder clang --debugger lldb --cflags '-O0 -g'
dexter_regression_test_command = ' '.join(
  # "python", "dexter.py", test, fail_mode, builder, debugger, cflags, ldflags
  ['"{}"'.format(sys.executable),
  '"{}"'.format(dexter_path),
  'test',
  '--fail-lt 1.0 -w',
  dexter_regression_test_builder,
  dexter_regression_test_debugger,
  dexter_regression_test_cflags,
  dexter_regression_test_ldflags])

tools.append(ToolSubst('%dexter_regression_test', dexter_regression_test_command))

tool_dirs = [config.llvm_tools_dir]

llvm_config.add_tool_substitutions(tools, tool_dirs)

lit.util.usePlatformSdkOnDarwin(config, lit_config)

# available_features: REQUIRES/UNSUPPORTED lit commands look at this list.
if platform.system() == 'Darwin':
    xcode_lldb_vers = subprocess.check_output(['xcrun', 'lldb', '--version']).decode("utf-8")
    match = re.search('lldb-(\d+)', xcode_lldb_vers)
    if match:
        apple_lldb_vers = int(match.group(1))
        if apple_lldb_vers < 1000:
            config.available_features.add('apple-lldb-pre-1000')

llvm_config.feature_config(
    [('--build-mode', {'Debug|RelWithDebInfo': 'debug-info'})]
)
