# -*- 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', 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()
