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

debugserver = lit.util.which('debugserver', 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 = 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:
    config.substitutions.append(('%debugserver', debugserver))

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()
