# ===----------------------------------------------------------------------===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===----------------------------------------------------------------------===##

"""
Lit test format for LLVM libc tests.

This format discovers pre-built test executables in the build directory
and runs them. It extends lit's ExecutableTest format.

The lit config sets test_source_root == test_exec_root (both to the build
directory), following the pattern used by llvm/test/Unit/lit.cfg.py.

Test executables are discovered by _isTestExecutable() and run by execute().

Integration tests that require command-line arguments or environment variables
have a sidecar <executable>.params file generated by CMake.  The format is
one arg per line, a "---" separator, then one KEY=VALUE env entry per line.
"""

import os
import shlex
import sys

import lit.formats
import lit.Test
import lit.util


kIsWindows = sys.platform in ["win32", "cygwin"]


class LibcTest(lit.formats.ExecutableTest):
    """
    Test format for libc unit tests.

    Extends ExecutableTest to discover pre-built test executables in the
    build directory rather than the source directory.
    """

    def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig):
        """
        Discover test executables in the build directory.

        Since test_source_root == test_exec_root (both point to build dir),
        we use getSourcePath() to find test executables.
        """
        source_path = testSuite.getSourcePath(path_in_suite)

        # Look for test executables in the build directory
        if not os.path.isdir(source_path):
            return

        # Sort for deterministic test discovery/output ordering.
        for filename in sorted(os.listdir(source_path)):
            filepath = os.path.join(source_path, filename)

            # Match our test executable pattern
            if self._isTestExecutable(filename, filepath, localConfig):
                # Create a test with the executable name
                yield lit.Test.Test(testSuite, path_in_suite + (filename,), localConfig)

    def _isTestExecutable(self, filename, filepath, localConfig):
        """
        Check if a file is a libc test executable we should run.

        Recognized patterns (all must end with .__build__, optionally followed
        by .exe on Windows):
          libc.test.src.<category>.<test_name>.__build__
          libc.test.src.<category>.<test_name>.__unit__[.<opts>...].__build__
          libc.test.src.<category>.<test_name>.__hermetic__[.<opts>...].__build__
          libc.test.include.<test_name>.__unit__[.<opts>...].__build__
          libc.test.include.<test_name>.__hermetic__[.<opts>...].__build__
          libc.test.integration.<category>.<test_name>.__build__
        """
        test_name = filename
        if kIsWindows and filename.endswith(".exe"):
            test_name = filename[: -len(".exe")]

        if not test_name.endswith(".__build__"):
            return False
        if test_name.startswith("libc.test.src."):
            pass  # Accept all src tests ending in .__build__
        elif test_name.startswith("libc.test.include."):
            if ".__unit__." not in test_name and ".__hermetic__." not in test_name:
                return False
        elif test_name.startswith("libc.test.integration."):
            pass  # Accept all integration tests ending in .__build__
        elif test_name.startswith("libc.test.shared."):
            pass  # Accept all shared tests ending in .__build__
        elif test_name.startswith("libc.test.utils."):
            pass  # Accept all utils tests ending in .__build__
        else:
            return False
        if not os.path.isfile(filepath):
            return False
        # GPU binaries are not host-executable but run via an emulator, so ignore X_OK if emulator is set.
        if (
            not kIsWindows
            and not os.access(filepath, os.X_OK)
            and not getattr(localConfig, "libc_crosscompiling_emulator", None)
        ):
            return False
        return True

    def _getParamsPath(self, test_path):
        params_path = test_path + ".params"
        if os.path.isfile(params_path):
            return params_path

        root, ext = os.path.splitext(test_path)
        if ext.lower() == ".exe":
            params_path = root + ".params"
            if os.path.isfile(params_path):
                return params_path

        return None

    def execute(self, test, litConfig):
        """
        Execute a test by running the test executable.

        Runs from the executable's directory so relative paths (like
        testdata/test.txt) work correctly.

        If a sidecar <executable>.params file exists, it supplies the
        command-line arguments and environment variables for the test.
        """

        test_path = test.getSourcePath()
        exec_dir = os.path.dirname(test_path)

        # Read optional sidecar .params file generated by CMake for tests that
        # need specific args/env (e.g. integration tests with ARGS/ENV).
        # Format: one arg per line, "---" separator, then KEY=VALUE env lines.
        loader_args = []
        test_args = []
        extra_env = {}
        params_path = self._getParamsPath(test_path)
        if params_path:
            with open(params_path) as f:
                content = f.read()
            sections = content.split("---\n")
            if len(sections) >= 3:
                loader_args = [l for l in sections[0].splitlines() if l]
                test_args = [l for l in sections[1].splitlines() if l]
                env_section = sections[2]
            else:
                loader_args = []
                test_args = [l for l in sections[0].splitlines() if l]
                env_section = sections[1] if len(sections) > 1 else ""

            for line in env_section.splitlines():
                if "=" in line:
                    k, _, v = line.partition("=")
                    extra_env[k] = v

        # Build the environment: inherit the current process environment, then
        # set PWD to exec_dir so getenv("PWD") matches getcwd(), then overlay
        # any test-specific variables from the .params file.
        env = dict(os.environ)
        env["PWD"] = exec_dir
        env.update(extra_env)

        test_cmd_template = getattr(test.config, "libc_test_cmd", "")
        if test_cmd_template:
            if "@BINARY@" in test_cmd_template:
                # Insert loader_args before the binary, and test_args after.
                prefix, _, suffix = test_cmd_template.partition("@BINARY@")
                cmd_args = (
                    shlex.split(prefix)
                    + loader_args
                    + [test_path]
                    + shlex.split(suffix)
                    + test_args
                )
            else:
                # Fallback to appending the binary path if @BINARY@ placeholder is missing.
                cmd_args = (
                    shlex.split(test_cmd_template)
                    + loader_args
                    + [test_path]
                    + test_args
                )
            if not cmd_args:
                cmd_args = [test_path]

            out, err, exit_code = lit.util.executeCommand(
                cmd_args, cwd=exec_dir, env=env
            )
        else:
            out, err, exit_code = lit.util.executeCommand(
                [test_path] + extra_args, cwd=exec_dir, env=env
            )

        if not exit_code:
            return lit.Test.PASS, ""

        return lit.Test.FAIL, out + err
