#!/usr/bin/env python3
"""
Check the invariants of the -inl.h files used by the precompiled mode:

* Every namespace-scope function definition is marked PYBIND11_INLINE.
* Every macro in a preprocessor condition is known. A macro that changes the
  code must either be the same for the library and the modules (platform,
  compiler, Python version), or be encoded in PYBIND11_PRECOMPILED_CONFIG_CHECK
  (detail/internals.h) and listed in docs/compiling.rst.
"""

from __future__ import annotations

import re
import sys
from pathlib import Path

# Same in the library and in the modules that link it.
ENVIRONMENT_MACROS = {
    "GRAALVM_PYTHON",
    "NDEBUG",
    "PYBIND11_BUILTIN_QUALNAME",
    "PYBIND11_HAS_STRING_VIEW",
    "PYBIND11_PRECOMPILED",
    "PYPY_VERSION",
    "PY_MAJOR_VERSION",
    "PY_MINOR_VERSION",
    "PY_VERSION_HEX",
    "Py_REF_DEBUG",
    "_MSC_VER",
    "_WIN32",
    "__GLIBCXX__",
    "__GNUC__",
    "__cpp_lib_unordered_map_try_emplace",
    "__clang__",
}

# Encoded in PYBIND11_PRECOMPILED_CONFIG_CHECK.
GUARDED_MACROS = {
    "PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET",
    "PYBIND11_DETAILED_ERROR_MESSAGES",
    "PYBIND11_HAS_SUBINTERPRETER_SUPPORT",
    "PYBIND11_INTERNALS_VERSION",
    "PYBIND11_SIMPLE_GIL_MANAGEMENT",
    "Py_GIL_DISABLED",
}

# Only change code inside the library; documented in docs/compiling.rst.
LIBRARY_ONLY_MACROS = {
    "PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING",
}

KNOWN_MACROS = ENVIRONMENT_MACROS | GUARDED_MACROS | LIBRARY_ONLY_MACROS

TOKENS = re.compile(
    r"""
    (?P<raw>R"(?P<delim>[^(\s]*)\(.*?\)(?P=delim)")
    | (?P<str>"(?:\\.|[^"\\\n])*")
    | (?P<chr>'(?:\\.|[^'\\\n])*')
    | (?P<line_comment>//[^\n]*)
    | (?P<block_comment>/\*.*?\*/)
    """,
    re.VERBOSE | re.DOTALL,
)
PP_CONDITION = re.compile(r"^[ \t]*#\s*(?:if|elif|ifdef|ifndef)\b(.*)$", re.MULTILINE)
PP_LINE = re.compile(r"^[ \t]*#.*$", re.MULTILINE)
NAMESPACE_MACRO = re.compile(
    r"^[ \t]*PYBIND11_(?:NAMESPACE_BEGIN|NAMESPACE_END|WARNING_\w+)\(.*\)[ \t]*$",
    re.MULTILINE,
)
IDENTIFIER = re.compile(r"\b[A-Za-z_]\w*\b")
NON_FUNCTION_BLOCK = re.compile(r"^(?:struct|class|union|enum)\b|=$")


def strip(text: str) -> str:
    """Blank out comments and string literals, keeping the line numbers."""

    def blank(match: re.Match[str]) -> str:
        if match.group("line_comment") or match.group("block_comment"):
            return re.sub(r"[^\n]", " ", match.group())
        return '""' + "\n" * match.group().count("\n")

    return TOKENS.sub(blank, text)


def check(path: Path) -> list[str]:
    text = strip(path.read_text(encoding="utf-8"))
    errors: list[str] = []

    for match in PP_CONDITION.finditer(text):
        line = text.count("\n", 0, match.start()) + 1
        errors.extend(
            f"{path}:{line}: unknown configuration macro {name}; see {Path(__file__).name}"
            for name in IDENTIFIER.findall(match.group(1))
            if name != "defined" and name not in KNOWN_MACROS
        )

    code = PP_LINE.sub(lambda m: " " * len(m.group()), text)
    code = NAMESPACE_MACRO.sub(lambda m: " " * len(m.group()), code)

    # One entry per open brace: True for namespace and extern "C" blocks, whose
    # contents are still at namespace scope.
    scopes: list[bool] = []
    start = 0
    for pos, char in enumerate(code):
        at_namespace_scope = all(scopes)
        if char == "{":
            if not at_namespace_scope:
                scopes.append(False)
                continue
            header = " ".join(code[start:pos].split())
            transparent = header == 'extern "C"' or header.startswith("namespace")
            if (
                not transparent
                and "(" in header
                and not NON_FUNCTION_BLOCK.search(header)
                and "PYBIND11_INLINE" not in header.split()
            ):
                offset = start + len(code[start:pos]) - len(code[start:pos].lstrip())
                line = code.count("\n", 0, offset) + 1
                errors.append(f"{path}:{line}: definition without PYBIND11_INLINE")
            scopes.append(transparent)
            if transparent:
                start = pos + 1
        elif char == "}":
            scopes.pop()
            if all(scopes):
                start = pos + 1
        elif char == ";" and at_namespace_scope:
            start = pos + 1

    return errors


def main(argv: list[str]) -> int:
    errors = [error for arg in argv for error in check(Path(arg))]
    for error in errors:
        print(error)
    return 1 if errors else 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
