# -*- 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 = []

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

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

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

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

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