# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import platform
import shlex
import shutil
import subprocess
import sys

import lit.formats

# name: The name of this test suite.
config.name = "lldb-api"

# suffixes: A list of file extensions to treat as test files.
config.suffixes = [".py"]

# 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, "test", "API")


def mkdir_p(path):
    import errno

    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    if not os.path.isdir(path):
        raise OSError(errno.ENOTDIR, "%s is not a directory" % path)


def find_sanitizer_runtime(name):
    resource_dir = (
        subprocess.check_output([config.cmake_cxx_compiler, "-print-resource-dir"])
        .decode("utf-8")
        .strip()
    )
    return os.path.join(resource_dir, "lib", "darwin", name)


def find_shlibpath_var():
    if platform.system() in ["Linux", "FreeBSD", "NetBSD", "OpenBSD", "SunOS"]:
        yield "LD_LIBRARY_PATH"
    elif platform.system() == "Darwin":
        yield "DYLD_LIBRARY_PATH"
    elif platform.system() == "Windows":
        yield "PATH"


# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
# binary as the ASan interceptors get loaded too late. Also, when SIP is
# enabled, we can't inject libraries into system binaries at all, so we need a
# copy of the "real" python to work with.
def find_python_interpreter():
    # This is only necessary when using DYLD_INSERT_LIBRARIES.
    if "DYLD_INSERT_LIBRARIES" not in config.environment:
        return None

    # If we're running in a virtual environment, we have to copy Python into
    # the virtual environment for it to work.
    if sys.prefix != sys.base_prefix:
        copied_python = os.path.join(sys.prefix, "bin", "copied-python")
    else:
        copied_python = os.path.join(config.lldb_build_directory, "copied-python")

    # Avoid doing any work if we already copied the binary.
    if os.path.isfile(copied_python):
        return copied_python

    # Find the "real" python binary.
    real_python = (
        subprocess.check_output(
            [
                config.python_executable,
                os.path.join(
                    os.path.dirname(os.path.realpath(__file__)),
                    "get_darwin_real_python.py",
                ),
            ]
        )
        .decode("utf-8")
        .strip()
    )

    shutil.copy(real_python, copied_python)

    # Now make sure the copied Python works. The Python in Xcode has a relative
    # RPATH and cannot be copied.
    try:
        # We don't care about the output, just make sure it runs.
        subprocess.check_call([copied_python, "-V"])
    except subprocess.CalledProcessError:
        # The copied Python didn't work. Assume we're dealing with the Python
        # interpreter in Xcode. Given that this is not a system binary SIP
        # won't prevent us form injecting the interceptors, but when running in
        # a virtual environment, we can't use it directly. Create a symlink
        # instead.
        os.remove(copied_python)
        os.symlink(real_python, copied_python)

    # The copied Python works.
    return copied_python


def is_configured(attr):
    """Return the configuration attribute if it exists and None otherwise.

    This allows us to check if the attribute exists before trying to access it."""
    return getattr(config, attr, None)


def delete_module_cache(path):
    """Clean the module caches in the test build directory.

    This is necessary in an incremental build whenever clang changes underneath,
    so doing it once per lit.py invocation is close enough."""
    if os.path.isdir(path):
        lit_config.note("Deleting module cache at %s." % path)
        shutil.rmtree(path)


if is_configured("llvm_use_sanitizer"):
    config.environment["MallocNanoZone"] = "0"
    if "Address" in config.llvm_use_sanitizer:
        config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"
        if "Darwin" in config.host_os:
            config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(
                "libclang_rt.asan_osx_dynamic.dylib"
            )

    if "Thread" in config.llvm_use_sanitizer:
        config.environment["TSAN_OPTIONS"] = "halt_on_error=1"
        if "Darwin" in config.host_os:
            config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(
                "libclang_rt.tsan_osx_dynamic.dylib"
            )

if platform.system() == "Darwin":
    python_executable = find_python_interpreter()
    if python_executable:
        lit_config.note(
            "Using {} instead of {}".format(python_executable, config.python_executable)
        )
        config.python_executable = python_executable

# Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.
if is_configured("shared_libs"):
    for shlibpath_var in find_shlibpath_var():
        # In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while
        # llvm_libs_dir specifies LLVM's lib directory.
        shlibpath = os.path.pathsep.join(
            (
                config.llvm_shlib_dir,
                config.llvm_libs_dir,
                config.environment.get(shlibpath_var, ""),
            )
        )
        config.environment[shlibpath_var] = shlibpath
    else:
        lit_config.warning(
            "unable to inject shared library path on '{}'".format(platform.system())
        )

lldb_use_simulator = lit_config.params.get("lldb-run-with-simulator", None)
if lldb_use_simulator:
    if lldb_use_simulator == "ios":
        lit_config.note("Running API tests on iOS simulator")
        config.available_features.add("lldb-simulator-ios")
    elif lldb_use_simulator == "watchos":
        lit_config.note("Running API tests on watchOS simulator")
        config.available_features.add("lldb-simulator-watchos")
    elif lldb_use_simulator == "tvos":
        lit_config.note("Running API tests on tvOS simulator")
        config.available_features.add("lldb-simulator-tvos")
    else:
        lit_config.error("Unknown simulator id '{}'".format(lldb_use_simulator))

# Set a default per-test timeout of 10 minutes. Setting a timeout per test
# requires that killProcessAndChildren() is supported on the platform and
# lit complains if the value is set but it is not supported.
supported, errormsg = lit_config.maxIndividualTestTimeIsSupported
if supported:
    lit_config.maxIndividualTestTime = 600
else:
    lit_config.warning("Could not set a default per-test timeout. " + errormsg)

# Build dotest command.
dotest_cmd = [os.path.join(config.lldb_src_root, "test", "API", "dotest.py")]

if is_configured("dotest_common_args_str"):
    dotest_cmd.extend(config.dotest_common_args_str.split(";"))

# Library path may be needed to locate just-built clang and libcxx.
if is_configured("llvm_libs_dir"):
    dotest_cmd += ["--env", "LLVM_LIBS_DIR=" + config.llvm_libs_dir]

# Include path may be needed to locate just-built libcxx.
if is_configured("llvm_include_dir"):
    dotest_cmd += ["--env", "LLVM_INCLUDE_DIR=" + config.llvm_include_dir]

# This path may be needed to locate required llvm tools
if is_configured("llvm_tools_dir"):
    dotest_cmd += ["--env", "LLVM_TOOLS_DIR=" + config.llvm_tools_dir]

# If we have a just-built libcxx, prefer it over the system one.
if is_configured("has_libcxx") and config.has_libcxx:
    if platform.system() != "Windows":
        if is_configured("libcxx_include_dir") and is_configured("libcxx_libs_dir"):
            dotest_cmd += ["--libcxx-include-dir", config.libcxx_include_dir]
            if is_configured("libcxx_include_target_dir"):
                dotest_cmd += [
                    "--libcxx-include-target-dir",
                    config.libcxx_include_target_dir,
                ]
            dotest_cmd += ["--libcxx-library-dir", config.libcxx_libs_dir]

# Forward ASan-specific environment variables to tests, as a test may load an
# ASan-ified dylib.
for env_var in ("ASAN_OPTIONS", "DYLD_INSERT_LIBRARIES"):
    if env_var in config.environment:
        dotest_cmd += ["--inferior-env", env_var + "=" + config.environment[env_var]]

if is_configured("test_arch"):
    dotest_cmd += ["--arch", config.test_arch]

if is_configured("lldb_build_directory"):
    dotest_cmd += ["--build-dir", config.lldb_build_directory]

if is_configured("lldb_module_cache"):
    delete_module_cache(config.lldb_module_cache)
    dotest_cmd += ["--lldb-module-cache-dir", config.lldb_module_cache]

if is_configured("clang_module_cache"):
    delete_module_cache(config.clang_module_cache)
    dotest_cmd += ["--clang-module-cache-dir", config.clang_module_cache]

if is_configured("lldb_executable"):
    dotest_cmd += ["--executable", config.lldb_executable]

if is_configured("test_compiler"):
    dotest_cmd += ["--compiler", config.test_compiler]

if is_configured("dsymutil"):
    dotest_cmd += ["--dsymutil", config.dsymutil]

if is_configured("make"):
    dotest_cmd += ["--make", config.make]

if is_configured("llvm_tools_dir"):
    dotest_cmd += ["--llvm-tools-dir", config.llvm_tools_dir]

if is_configured("server"):
    dotest_cmd += ["--server", config.server]

if is_configured("lldb_obj_root"):
    dotest_cmd += ["--lldb-obj-root", config.lldb_obj_root]

if is_configured("lldb_libs_dir"):
    dotest_cmd += ["--lldb-libs-dir", config.lldb_libs_dir]

if is_configured("lldb_framework_dir"):
    dotest_cmd += ["--framework", config.lldb_framework_dir]

if "lldb-simulator-ios" in config.available_features:
    dotest_cmd += ["--apple-sdk", "iphonesimulator", "--platform-name", "ios-simulator"]
elif "lldb-simulator-watchos" in config.available_features:
    dotest_cmd += [
        "--apple-sdk",
        "watchsimulator",
        "--platform-name",
        "watchos-simulator",
    ]
elif "lldb-simulator-tvos" in config.available_features:
    dotest_cmd += [
        "--apple-sdk",
        "appletvsimulator",
        "--platform-name",
        "tvos-simulator",
    ]

if is_configured("enabled_plugins"):
    for plugin in config.enabled_plugins:
        dotest_cmd += ["--enable-plugin", plugin]

# `dotest` args come from three different sources:
# 1. Derived by CMake based on its configs (LLDB_TEST_COMMON_ARGS), which end
# up in `dotest_common_args_str`.
# 2. CMake user parameters (LLDB_TEST_USER_ARGS), which end up in
# `dotest_user_args_str`.
# 3. With `llvm-lit "--param=dotest-args=..."`, which end up in
# `dotest_lit_args_str`.
# Check them in this order, so that more specific overrides are visited last.
# In particular, (1) is visited at the top of the file, since the script
# derives other information from it.

if is_configured("lldb_platform_url"):
    dotest_cmd += ["--platform-url", config.lldb_platform_url]
if is_configured("lldb_platform_working_dir"):
    dotest_cmd += ["--platform-working-dir", config.lldb_platform_working_dir]
if is_configured("cmake_sysroot"):
    dotest_cmd += ["--sysroot", config.cmake_sysroot]

if is_configured("dotest_user_args_str"):
    dotest_cmd.extend(config.dotest_user_args_str.split(";"))

if is_configured("dotest_lit_args_str"):
    # We don't want to force users passing arguments to lit to use `;` as a
    # separator. We use Python's simple lexical analyzer to turn the args into a
    # list. Pass there arguments last so they can override anything that was
    # already configured.
    dotest_cmd.extend(shlex.split(config.dotest_lit_args_str))

# Load LLDB test format.
sys.path.append(os.path.join(config.lldb_src_root, "test", "API"))
import lldbtest

# testFormat: The test format to use to interpret tests.
config.test_format = lldbtest.LLDBTest(dotest_cmd)

# Propagate TERM or default to vt100.
config.environment["TERM"] = os.getenv("TERM", default="vt100")

# Propagate FREEBSD_LEGACY_PLUGIN
if "FREEBSD_LEGACY_PLUGIN" in os.environ:
    config.environment["FREEBSD_LEGACY_PLUGIN"] = os.environ["FREEBSD_LEGACY_PLUGIN"]

# Propagate XDG_CACHE_HOME
if "XDG_CACHE_HOME" in os.environ:
    config.environment["XDG_CACHE_HOME"] = os.environ["XDG_CACHE_HOME"]

# Transfer some environment variables into the tests on Windows build host.
if platform.system() == "Windows":
    for v in ["SystemDrive"]:
        if v in os.environ:
            config.environment[v] = os.environ[v]
