"""Generate the "Python API enumerators and constants" documentation page.

LLDB exposes the enumerators from `lldb-enumerations.h` and the constants from
`lldb-defines.h` as attributes of the `lldb` Python module. This script parses
those two headers and emits a Markdown page documenting every public value, so
the page can no longer drift out of sync with the source the way a
hand-maintained copy does.

The page is generated at build time and pulled into `python_api_enums.md` via
the `{build-include}` directive (see `lldb/docs/_ext/build_include.py`).
"""

import argparse
import re
from collections.abc import Iterator
from dataclasses import dataclass, field

# Matches a full enum declaration, capturing the name and the body. Covers
# plain `enum Name { ... }`, scoped `enum Name : type { ... }`, and the
# `FLAGS_ENUM(Name){ ... }` / `FLAGS_ANONYMOUS_ENUM(){ ... }` macros from
# lldb-enumerations.h. Capturing the body up to the first `}` relies on no `}`
# appearing inside an enum body or its comments, which holds for that header.
ENUM_RE = re.compile(
    r"(?:enum\s+(?P<name>\w+)\s*(?::\s*[\w:]+\s*)?"
    r"|FLAGS_ENUM\(\s*(?P<flags_name>\w+)\s*\)"
    r"|FLAGS_ANONYMOUS_ENUM\(\s*\))\s*\{\s*(?P<body>[^}]+)\s*\}"
)

# Doxygen inline commands that wrap a following word for emphasis or reference.
# We drop the command itself and keep its argument.
DOXYGEN_CMD_RE = re.compile(r"\\(?:a|b|c|e|p|ref|see|link|endlink)\b\s?")

# Constants are grouped editorially to match the long-standing layout of the
# page. The classifier is prefix-based so new constants land in a sensible
# group without further maintenance; anything unrecognized falls into
# "Miscellaneous constants".
CONSTANT_GROUP_ORDER = [
    "Generic register numbers",
    "Invalid value definitions",
    "CPU types",
    "Option set definitions",
    "Miscellaneous constants",
]


def slugify(text: str) -> str:
    return re.sub(r"[^a-z0-9]+", "-", text.lower()).strip("-")


def clean_comment(text: str) -> str:
    """Strip a doc-comment fragment down to its prose."""
    return DOXYGEN_CMD_RE.sub("", text).rstrip()


@dataclass
class Member:
    name: str
    desc: list[str] = field(default_factory=list)  # lines; "" marks a paragraph break


def parse_enum_body(body: str) -> list[Member]:
    """Parse the body of an enum into a list of documented members.

    Comment association follows Doxygen conventions, with one accommodation for
    the header's occasional misuse of `///<` on its own line as a *leading*
    comment (see WatchpointValueKind): a trailing `///<` documents the member on
    its own line, while a standalone doc comment that isn't continuing a
    trailing comment is treated as a leading comment for the next member.
    """
    members = []
    pending_lead = []  # leading doc lines awaiting the next member
    current = None  # most recently named member (target of trailing comments)
    in_trailing = False  # currently extending a member's trailing comment
    awaiting_name = True  # next identifier starts a new member
    depth = 0  # parenthesis nesting, to find top-level commas

    def attach_lead(member: Member) -> None:
        # Drop a leading line that merely repeats the member name (the style
        # used by CommandFlags) along with its trailing blank.
        lead = pending_lead[:]
        while lead and lead[0] == "":
            lead.pop(0)
        if lead and lead[0] == member.name:
            lead.pop(0)
            while lead and lead[0] == "":
                lead.pop(0)
        member.desc.extend(lead)

    for line in body.splitlines():
        comment_start = line.find("//")
        if comment_start == -1:
            code, comment = line, None
        else:
            code, comment = line[:comment_start], line[comment_start:]

        # Walk the code, picking out member names and top-level commas.
        i = 0
        while i < len(code):
            ch = code[i]
            if ch == "(":
                depth += 1
            elif ch == ")":
                depth -= 1
                assert depth >= 0
            elif ch == "," and depth == 0:
                awaiting_name = True
            elif awaiting_name and (ch.isalpha() or ch == "_"):
                j = i
                while j < len(code) and (code[j].isalnum() or code[j] == "_"):
                    j += 1
                name = code[i:j]
                current = Member(name)
                attach_lead(current)
                pending_lead = []
                in_trailing = False
                awaiting_name = False
                # Only public enumerators (the `e` prefix) are documented;
                # `k`-prefixed sentinels like kNumFormats are internal.
                if name.startswith("e"):
                    members.append(current)
                i = j
                continue
            i += 1

        if comment is not None:
            has_code = bool(code.strip())
            if comment.startswith("///<"):
                text = clean_comment(comment.removeprefix("///<").lstrip())
                if has_code and current is not None:
                    current.desc.append(text)
                    in_trailing = True
                elif in_trailing and current is not None:
                    current.desc.append(text)
                else:
                    pending_lead.append(text)
            elif comment.startswith("///"):
                text = clean_comment(comment.removeprefix("///").lstrip())
                if has_code and current is not None:
                    current.desc.append(text)
                    in_trailing = True
                elif in_trailing and current is not None:
                    current.desc.append(text)
                else:
                    pending_lead.append(text)
            # A plain `//` comment is an internal note; ignore it.
        elif not code.strip():
            # Blank line: ends any trailing-comment continuation and separates
            # paragraphs in an accumulating leading comment.
            in_trailing = False
            if pending_lead and pending_lead[-1] != "":
                pending_lead.append("")

    return members


def parse_enums(text: str) -> Iterator[tuple[str, list[str], list[Member]]]:
    """Yield (name, description_lines, members) for each enum in the header."""
    for match in ENUM_RE.finditer(text):
        name = match.group("name") or match.group("flags_name")
        if name is None:
            continue  # anonymous flag enums have no name to document
        members = parse_enum_body(match.group("body"))
        if not members:
            continue
        yield name, leading_description(text[: match.start()]), members


def leading_description(preceding_text: str) -> list[str]:
    """Collect the `///` doc comment immediately above a declaration."""
    lines = []
    for line in reversed(preceding_text.splitlines()):
        if not line.strip().startswith("//"):
            break
        lines.append(line)
    lines.reverse()

    desc = []
    for line in lines:
        stripped = line.strip()
        if stripped.startswith("///"):
            desc.append(clean_comment(stripped.removeprefix("///").lstrip()))
    while desc and desc[0] == "":
        desc.pop(0)
    while desc and desc[-1] == "":
        desc.pop()
    return desc


def classify_constant(name: str) -> str:
    if name.startswith("LLDB_REGNUM_GENERIC_"):
        return "Generic register numbers"
    if name == "LLDB_INVALID_CPUTYPE" or name.startswith("LLDB_ARCH_"):
        return "CPU types"
    if name.startswith("LLDB_INVALID_"):
        return "Invalid value definitions"
    if name == "LLDB_MAX_NUM_OPTION_SETS" or name.startswith("LLDB_OPT_SET_"):
        return "Option set definitions"
    return "Miscellaneous constants"


def parse_constants(text: str) -> dict[str, list[Member]]:
    """Parse value `#define LLDB_*` constants grouped for presentation."""
    # Join backslash line continuations so a define and its trailing comment
    # form a single logical line.
    logical = re.sub(r"\\\n", " ", text)

    groups = {name: [] for name in CONSTANT_GROUP_ORDER}
    # A `(` immediately after the name (no space) marks a function-like macro;
    # a `(` after whitespace is just a parenthesized value like `(1u << 0)`.
    define_re = re.compile(r"^#define\s+(LLDB_\w+)(\()?(.*)$")
    for line in logical.splitlines():
        match = define_re.match(line.strip())
        if not match:
            continue
        name, is_macro, rest = match.groups()
        if is_macro:
            continue  # function-like macro, not a Python-visible constant
        if not rest.strip():
            continue  # value-less define such as the include guard
        desc = ""
        comment_start = rest.find("//")
        if comment_start != -1:
            desc = clean_comment(rest[comment_start:].lstrip("/").lstrip())
        groups[classify_constant(name)].append(Member(name, [desc] if desc else []))
    return groups


def format_directive(out: list[str], member: Member) -> None:
    out.append("```{eval-rst}")
    out.append(f".. py:data:: {member.name}")
    desc = member.desc[:]
    while desc and desc[0] == "":
        desc.pop(0)
    while desc and desc[-1] == "":
        desc.pop()
    if desc:
        out.append("")
        for line in desc:
            out.append(f"   {line}" if line else "")
    out.append("```")
    out.append("")


def format_paragraphs(out: list[str], lines: list[str]) -> None:
    for line in lines:
        out.append(line)
    if lines:
        out.append("")


def generate(enums_text: str, defines_text: str) -> str:
    out = []
    out.append("# Python API enumerators and constants")
    out.append("")
    out.append("```{eval-rst}")
    out.append(".. py:currentmodule:: lldb")
    out.append("```")
    out.append("")

    out.append("## Constants")
    out.append("")
    groups = parse_constants(defines_text)
    for group in CONSTANT_GROUP_ORDER:
        members = groups[group]
        if not members:
            continue
        out.append(f"({slugify(group)})=")
        out.append("")
        out.append(f"### {group}")
        out.append("")
        for member in members:
            format_directive(out, member)

    out.append("## Enumerators")
    out.append("")
    for name, desc, members in parse_enums(enums_text):
        out.append(f"({name.lower()})=")
        out.append("")
        out.append(f"### {name}")
        out.append("")
        format_paragraphs(out, desc)
        for member in members:
            format_directive(out, member)

    return "\n".join(out).rstrip() + "\n"


def main() -> None:
    parser = argparse.ArgumentParser(
        prog="gen-python-api-enums",
        description="Generate the Python API enums/constants doc from headers",
    )
    parser.add_argument(
        "--enumerations", required=True, help="Path to lldb-enumerations.h"
    )
    parser.add_argument("--defines", required=True, help="Path to lldb-defines.h")
    parser.add_argument("-o", "--output", required=True, help="Path to output file")
    args = parser.parse_args()

    with open(args.enumerations, encoding="utf-8") as f:
        enums_text = f.read()
    with open(args.defines, encoding="utf-8") as f:
        defines_text = f.read()

    with open(args.output, "w", encoding="utf-8") as f:
        f.write(generate(enums_text, defines_text))


if __name__ == "__main__":
    main()
