# -*- Python -*-

import os
import platform
import re
import subprocess
import locale

import lit.formats
import lit.util

def binary_feature(on, feature, off_prefix):
  return feature if on else off_prefix + feature

# Configuration file for the 'lit' test runner.

# name: The name of this test suite.
config.name = 'lldb'

# 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.
execute_external = (platform.system() != 'Windows'
                    or lit_config.getBashPath() not in [None, ""])
config.test_format = lit.formats.ShTest(execute_external)

# suffixes: We only support unit tests
config.suffixes = []

config.excludes = ['Inputs']

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

# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.join(config.lldb_obj_root, 'lit')

# Tweak the PATH to include the tools dir and the scripts dir.
lldb_tools_dir = config.lldb_tools_dir
llvm_tools_dir = config.llvm_tools_dir
path = os.path.pathsep.join((config.lldb_tools_dir, config.llvm_tools_dir, config.environment['PATH']))

config.environment['PATH'] = path

path = os.path.pathsep.join((config.lldb_libs_dir, config.llvm_libs_dir,
                              config.environment.get('LD_LIBRARY_PATH','')))
config.environment['LD_LIBRARY_PATH'] = path

# Propagate LLVM_SRC_ROOT into the environment.
config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '')

# Propagate PYTHON_EXECUTABLE into the environment
config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', '')

# Register substitutions
config.substitutions.append(('%python', '"%s"' % (config.python_executable)))

if platform.system() in ['Darwin']:
    debugserver = lit.util.which('debugserver', lldb_tools_dir)
else:
    debugserver = lit.util.which('lldb-server', lldb_tools_dir)
lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir),
                               config.test_source_root)

lldbmi = lit.util.which('lldb-mi', lldb_tools_dir)

if not os.path.exists(config.cc):
    config.cc = lit.util.which(config.cc, config.environment['PATH'])

if not os.path.exists(config.cxx):
    config.cxx = lit.util.which(config.cxx, config.environment['PATH'])

if platform.system() in ['Darwin']:
    try:
        out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip()
        res = 0
    except OSError:
        res = -1
    if res == 0 and out:
        sdk_path = lit.util.to_string(out)
        lit_config.note('using SDKROOT: %r' % sdk_path)
        config.cc += " -isysroot %s" % sdk_path
        config.cxx += " -isysroot %s" % sdk_path

if platform.system() in ['OpenBSD']:
    config.cc += " -pthread"
    config.cxx += " -pthread"

config.substitutions.append(('%cc', config.cc))
config.substitutions.append(('%cxx', config.cxx))

config.substitutions.append(('%lldbmi', lldbmi + " --synchronous"))
config.substitutions.append(('%lldb', lldb))

if debugserver is not None:
    if platform.system() in ['Darwin']:
        config.substitutions.append(('%debugserver', debugserver))
    else:
        config.substitutions.append(('%debugserver', debugserver + ' gdbserver'))

for pattern in [r"\bFileCheck\b",
                r"\blldb-test\b",
                r"\byaml2obj\b",
                r"\| \bnot\b"]:
    tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                          pattern)
    tool_pipe = tool_match.group(2)
    tool_name = tool_match.group(4)
    tool_path = lit.util.which(tool_name, config.environment['PATH'])
    if not tool_path:
        # Warn, but still provide a substitution.
        lit_config.note(
            'Did not find ' + tool_name + ' in ' + config.environment['PATH'])
    config.substitutions.append((pattern, tool_pipe + tool_path))

# Shell execution
if platform.system() not in ['Windows'] or lit_config.getBashPath() != '':
    config.available_features.add('shell')

# Running on Darwin OS
if platform.system() in ['Darwin']:
    config.available_features.add('darwin')
    config.available_features.add('system-linker-mach-o')

# Running on ELF based *nix
if platform.system() in ['FreeBSD', 'Linux']:
    config.available_features.add('system-linker-elf')
    if platform.system() in ['FreeBSD']:
        config.available_features.add('freebsd')
    else:
        config.available_features.add('linux')

config.available_features.add(
    binary_feature(platform.system() in ['Windows'], 'windows', 'no'))

if re.match(r'^arm(hf.*-linux)|(.*-linux-gnuabihf)', config.target_triple):
    config.available_features.add("armhf-linux")

if re.match(r'icc', config.cc):
    config.available_features.add("compiler-icc")
elif re.match(r'clang', config.cc):
    config.available_features.add("compiler-clang")
elif re.match(r'gcc', config.cc):
    config.available_features.add("compiler-gcc")
elif re.match(r'cl', config.cc):
    config.available_features.add("compiler-msvc")

config.available_features.add(binary_feature(config.have_zlib, "zlib", "no"))
if config.have_lld:
  config.available_features.add("lld")

# llvm-config knows whether it is compiled with asserts (and)
# whether we are operating in release/debug mode.
import subprocess
try:
    llvm_config_cmd = \
     subprocess.Popen([os.path.join(llvm_tools_dir, 'llvm-config'),
                     '--build-mode', '--assertion-mode', '--targets-built'],
                      stdout = subprocess.PIPE)
except OSError as why:
    print("Could not find llvm-config in " + llvm_tools_dir)
    exit(42)

llvm_config_output = llvm_config_cmd.stdout.read().decode('utf_8')
llvm_config_output_list = llvm_config_output.split("\n")

if re.search(r'DEBUG', llvm_config_output_list[0]):
    config.available_features.add('debug')
if re.search(r'ON', llvm_config_output_list[1]):
    config.available_features.add('asserts')
if re.search(r'ARM', llvm_config_output_list[2]):
    config.available_features.add('arm')
if re.search(r'Mips', llvm_config_output_list[2]):
    config.available_features.add('mips')
if re.search(r'PowerPC', llvm_config_output_list[2]):
    config.available_features.add('powerpc')
if re.search(r'X86', llvm_config_output_list[2]):
    config.available_features.add('x86')
llvm_config_cmd.wait()
