""" This module contains functions used by the test cases to hide the
architecture and/or the platform dependent nature of the tests. """

# System modules
import itertools
import json
import re
import subprocess
import sys
import os
from packaging import version
from urllib.parse import urlparse

# LLDB modules
import lldb
from . import configuration
from . import lldbtest_config
import lldbsuite.test.lldbplatform as lldbplatform
from lldbsuite.test.builders import get_builder
from lldbsuite.test.lldbutil import is_exe


def check_first_register_readable(test_case):
    arch = test_case.getArchitecture()

    if arch in ["x86_64", "i386"]:
        test_case.expect("register read eax", substrs=["eax = 0x"])
    elif arch in ["arm", "armv7", "armv7k", "armv8l", "armv7l"]:
        test_case.expect("register read r0", substrs=["r0 = 0x"])
    elif arch in ["aarch64", "arm64", "arm64e", "arm64_32"]:
        test_case.expect("register read x0", substrs=["x0 = 0x"])
    elif re.match("mips", arch):
        test_case.expect("register read zero", substrs=["zero = 0x"])
    elif arch in ["s390x"]:
        test_case.expect("register read r0", substrs=["r0 = 0x"])
    elif arch in ["powerpc64le"]:
        test_case.expect("register read r0", substrs=["r0 = 0x"])
    elif arch in ["riscv64", "riscv32"]:
        test_case.expect("register read zero", substrs=["zero = 0x"])
    else:
        # TODO: Add check for other architectures
        test_case.fail(
            "Unsupported architecture for test case (arch: %s)"
            % test_case.getArchitecture()
        )


def _run_adb_command(cmd, device_id):
    device_id_args = []
    if device_id:
        device_id_args = ["-s", device_id]
    full_cmd = ["adb"] + device_id_args + cmd
    p = subprocess.Popen(full_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    return p.returncode, stdout, stderr


def target_is_android():
    return configuration.lldb_platform_name == "remote-android"


def android_device_api():
    if not hasattr(android_device_api, "result"):
        assert configuration.lldb_platform_url is not None
        device_id = None
        parsed_url = urlparse(configuration.lldb_platform_url)
        host_name = parsed_url.netloc.split(":")[0]
        if host_name != "localhost":
            device_id = host_name
            if device_id.startswith("[") and device_id.endswith("]"):
                device_id = device_id[1:-1]
        retcode, stdout, stderr = _run_adb_command(
            ["shell", "getprop", "ro.build.version.sdk"], device_id
        )
        if retcode == 0:
            android_device_api.result = int(stdout)
        else:
            raise LookupError(
                ">>> Unable to determine the API level of the Android device.\n"
                ">>> stdout:\n%s\n"
                ">>> stderr:\n%s\n" % (stdout, stderr)
            )
    return android_device_api.result


def match_android_device(device_arch, valid_archs=None, valid_api_levels=None):
    if not target_is_android():
        return False
    if valid_archs is not None and device_arch not in valid_archs:
        return False
    if valid_api_levels is not None and android_device_api() not in valid_api_levels:
        return False

    return True


def finalize_build_dictionary(dictionary):
    # Provide uname-like platform name
    platform_name_to_uname = {
        "linux": "Linux",
        "netbsd": "NetBSD",
        "freebsd": "FreeBSD",
        "windows": "Windows_NT",
        "macosx": "Darwin",
        "darwin": "Darwin",
    }

    if dictionary is None:
        dictionary = {}
    if target_is_android():
        dictionary["OS"] = "Android"
        dictionary["PIE"] = 1
    elif platformIsDarwin():
        dictionary["OS"] = "Darwin"
    else:
        dictionary["OS"] = platform_name_to_uname[getPlatform()]

    dictionary["HOST_OS"] = platform_name_to_uname[getHostPlatform()]

    return dictionary


def _get_platform_os(p):
    # Use the triple to determine the platform if set.
    triple = p.GetTriple()
    if triple:
        platform = triple.split("-")[2]
        if platform.startswith("freebsd"):
            platform = "freebsd"
        elif platform.startswith("netbsd"):
            platform = "netbsd"
        elif platform.startswith("openbsd"):
            platform = "openbsd"
        return platform

    return ""


def getHostPlatform():
    """Returns the host platform running the test suite."""
    return _get_platform_os(lldb.SBPlatform("host"))


def getDarwinOSTriples():
    return lldbplatform.translate(lldbplatform.darwin_all)


def getPlatform():
    """Returns the target platform which the tests are running on."""
    # Use the Apple SDK to determine the platform if set.
    if configuration.apple_sdk:
        platform = configuration.apple_sdk
        dot = platform.find(".")
        if dot != -1:
            platform = platform[:dot]
        if platform == "iphoneos":
            platform = "ios"
        return platform

    return _get_platform_os(lldb.selected_platform)


def platformIsDarwin():
    """Returns true if the OS triple for the selected platform is any valid apple OS"""
    return getPlatform() in getDarwinOSTriples()


def findMainThreadCheckerDylib():
    if not platformIsDarwin():
        return ""

    if getPlatform() in lldbplatform.translate(lldbplatform.darwin_embedded):
        return "/Developer/usr/lib/libMainThreadChecker.dylib"

    with os.popen("xcode-select -p") as output:
        xcode_developer_path = output.read().strip()
        mtc_dylib_path = "%s/usr/lib/libMainThreadChecker.dylib" % xcode_developer_path
        if os.path.isfile(mtc_dylib_path):
            return mtc_dylib_path

    return ""


def findBacktraceRecordingDylib():
    if not platformIsDarwin():
        return ""

    if getPlatform() in lldbplatform.translate(lldbplatform.darwin_embedded):
        return "/Developer/usr/lib/libBacktraceRecording.dylib"

    with os.popen("xcode-select -p") as output:
        xcode_developer_path = output.read().strip()
        mtc_dylib_path = "%s/usr/lib/libBacktraceRecording.dylib" % xcode_developer_path
        if os.path.isfile(mtc_dylib_path):
            return mtc_dylib_path

    return ""


class _PlatformContext(object):
    """Value object class which contains platform-specific options."""

    def __init__(
        self, shlib_environment_var, shlib_path_separator, shlib_prefix, shlib_extension
    ):
        self.shlib_environment_var = shlib_environment_var
        self.shlib_path_separator = shlib_path_separator
        self.shlib_prefix = shlib_prefix
        self.shlib_extension = shlib_extension


def createPlatformContext():
    if platformIsDarwin():
        return _PlatformContext("DYLD_LIBRARY_PATH", ":", "lib", "dylib")
    elif getPlatform() in ("linux", "freebsd", "netbsd", "openbsd"):
        return _PlatformContext("LD_LIBRARY_PATH", ":", "lib", "so")
    else:
        return _PlatformContext("PATH", ";", "", "dll")


def hasChattyStderr(test_case):
    """Some targets produce garbage on the standard error output. This utility function
    determines whether the tests can be strict about the expected stderr contents."""
    if match_android_device(
        test_case.getArchitecture(), ["aarch64"], range(22, 25 + 1)
    ):
        return True  # The dynamic linker on the device will complain about unknown DT entries
    return False


def builder_module():
    """Return the builder for the target platform."""
    return get_builder(getPlatform())


def getArchitecture():
    """Returns the architecture in effect the test suite is running with."""
    module = builder_module()
    arch = module.getArchitecture()
    if arch == "amd64":
        arch = "x86_64"
    if arch in ["armv7l", "armv8l"]:
        arch = "arm"
    if re.match("rv64*", arch):
        arch = "riscv64"
    if re.match("rv32*", arch):
        arch = "riscv32"
    return arch


lldbArchitecture = None


def getLLDBArchitecture():
    """Returns the architecture of the lldb binary."""
    global lldbArchitecture
    if not lldbArchitecture:
        # These two target settings prevent lldb from doing setup that does
        # nothing but slow down the end goal of printing the architecture.
        command = [
            lldbtest_config.lldbExec,
            "-x",
            "-b",
            "-o",
            "settings set target.preload-symbols false",
            "-o",
            "settings set target.load-script-from-symbol-file false",
            "-o",
            "file " + lldbtest_config.lldbExec,
        ]

        output = subprocess.check_output(command)
        str = output.decode()

        for line in str.splitlines():
            m = re.search(r"Current executable set to '.*' \((.*)\)\.", line)
            if m:
                lldbArchitecture = m.group(1)
                break

    return lldbArchitecture


def getCompiler():
    """Returns the compiler in effect the test suite is running with."""
    module = builder_module()
    return module.getCompiler()


def getCompilerVersion():
    """Returns a string that represents the compiler version.
    Supports: llvm, clang.
    """
    version_output = subprocess.check_output(
        [getCompiler(), "--version"], errors="replace"
    )
    m = re.search("version ([0-9.]+)", version_output)
    if m:
        return m.group(1)
    return "unknown"


def getDwarfVersion():
    """Returns the dwarf version generated by clang or '0'."""
    if configuration.dwarf_version:
        return str(configuration.dwarf_version)
    if "clang" in getCompiler():
        try:
            triple = builder_module().getTriple(getArchitecture())
            target = ["-target", triple] if triple else []
            driver_output = subprocess.check_output(
                [getCompiler()] + target + "-g -c -x c - -o - -###".split(),
                stderr=subprocess.STDOUT,
            )
            driver_output = driver_output.decode("utf-8")
            for line in driver_output.split(os.linesep):
                m = re.search("dwarf-version=([0-9])", line)
                if m:
                    return m.group(1)
        except subprocess.CalledProcessError:
            pass
    return "0"


def expectedCompilerVersion(compiler_version):
    """Returns True iff compiler_version[1] matches the current compiler version.
    Use compiler_version[0] to specify the operator used to determine if a match has occurred.
    Any operator other than the following defaults to an equality test:
        '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'

    If the current compiler version cannot be determined, we assume it is close to the top
    of trunk, so any less-than or equal-to comparisons will return False, and any
    greater-than or not-equal-to comparisons will return True.
    """
    if compiler_version is None:
        return True
    operator = str(compiler_version[0])
    version_str = str(compiler_version[1])

    if not version_str:
        return True

    test_compiler_version_str = getCompilerVersion()
    if test_compiler_version_str == "unknown":
        # Assume the compiler version is at or near the top of trunk.
        return operator in [">", ">=", "!", "!=", "not"]

    actual_version = version.parse(version_str)
    test_compiler_version = version.parse(test_compiler_version_str)

    if operator == ">":
        return test_compiler_version > actual_version
    if operator == ">=" or operator == "=>":
        return test_compiler_version >= actual_version
    if operator == "<":
        return test_compiler_version < actual_version
    if operator == "<=" or operator == "=<":
        return test_compiler_version <= actual_version
    if operator == "!=" or operator == "!" or operator == "not":
        return version_str not in test_compiler_version_str
    return version_str in test_compiler_version_str


def expectedCompiler(compilers):
    """Returns True iff any element of compilers is a sub-string of the current compiler."""
    if compilers is None:
        return True

    for compiler in compilers:
        if compiler in getCompiler():
            return True

    return False


# This is a helper function to determine if a specific version of Xcode's linker
# contains a TLS bug. We want to skip TLS tests if they contain this bug, but
# adding a linker/linker_version conditions to a decorator is challenging due to
# the number of ways linkers can enter the build process.
def xcode15LinkerBug():
    """Returns true iff a test is running on a darwin platform and the host linker is between versions 1000 and 1109."""
    darwin_platforms = lldbplatform.translate(lldbplatform.darwin_all)
    if getPlatform() not in darwin_platforms:
        return False

    try:
        raw_version_details = subprocess.check_output(
            ("xcrun", "ld", "-version_details")
        )
        version_details = json.loads(raw_version_details)
        version = version_details.get("version", "0")
        version_tuple = tuple(int(x) for x in version.split("."))
        if (1000,) <= version_tuple <= (1109,):
            return True
    except:
        pass

    return False
