"""Support annotations for C API elements.

* Reference count annotations for C API functions.
* Stable ABI annotations
* Limited API annotations

Configuration:
* Set ``refcount_file`` to the path to the reference count data file.
* Set ``stable_abi_file`` to the path to stable ABI list.
"""

from __future__ import annotations

import csv
import dataclasses
from pathlib import Path
from typing import TYPE_CHECKING

from docutils import nodes
from docutils.statemachine import StringList
from sphinx import addnodes
from sphinx.locale import _ as sphinx_gettext
from sphinx.util.docutils import SphinxDirective

if TYPE_CHECKING:
    from sphinx.application import Sphinx
    from sphinx.util.typing import ExtensionMetadata

ROLE_TO_OBJECT_TYPE = {
    "func": "function",
    "macro": "macro",
    "member": "member",
    "type": "type",
    "data": "var",
}


@dataclasses.dataclass(slots=True)
class RefCountEntry:
    # Name of the function.
    name: str
    # List of (argument name, type, refcount effect) tuples.
    # (Currently not used. If it was, a dataclass might work better.)
    args: list = dataclasses.field(default_factory=list)
    # Return type of the function.
    result_type: str = ""
    # Reference count effect for the return value.
    result_refs: int | None = None


@dataclasses.dataclass(frozen=True, slots=True)
class StableABIEntry:
    # Role of the object.
    # Source: Each [item_kind] in stable_abi.toml is mapped to a C Domain role.
    role: str
    # Name of the object.
    # Source: [<item_kind>.*] in stable_abi.toml.
    name: str
    # Version when the object was added to the stable ABI.
    # (Source: [<item_kind>.*.added] in stable_abi.toml.
    added: str
    # An explananatory blurb for the ifdef.
    # Source: ``feature_macro.*.doc`` in stable_abi.toml.
    ifdef_note: str
    # Defines how much of the struct is exposed. Only relevant for structs.
    # Source: [<item_kind>.*.struct_abi_kind] in stable_abi.toml.
    struct_abi_kind: str


def read_refcount_data(refcount_filename: Path) -> dict[str, RefCountEntry]:
    refcount_data = {}
    refcounts = refcount_filename.read_text(encoding="utf8")
    for line in refcounts.splitlines():
        line = line.strip()
        if not line or line.startswith("#"):
            # blank lines and comments
            continue

        # Each line is of the form
        # function ':' type ':' [param name] ':' [refcount effect] ':' [comment]
        parts = line.split(":", 4)
        if len(parts) != 5:
            raise ValueError(f"Wrong field count in {line!r}")
        function, type, arg, refcount, _comment = parts

        # Get the entry, creating it if needed:
        try:
            entry = refcount_data[function]
        except KeyError:
            entry = refcount_data[function] = RefCountEntry(function)
        if not refcount or refcount == "null":
            refcount = None
        else:
            refcount = int(refcount)
        # Update the entry with the new parameter
        # or the result information.
        if arg:
            entry.args.append((arg, type, refcount))
        else:
            entry.result_type = type
            entry.result_refs = refcount

    return refcount_data


def read_stable_abi_data(stable_abi_file: Path) -> dict[str, StableABIEntry]:
    stable_abi_data = {}
    with open(stable_abi_file, encoding="utf8") as fp:
        for record in csv.DictReader(fp):
            name = record["name"]
            stable_abi_data[name] = StableABIEntry(**record)

    return stable_abi_data


def add_annotations(app: Sphinx, doctree: nodes.document) -> None:
    state = app.env.domaindata["c_annotations"]
    refcount_data = state["refcount_data"]
    stable_abi_data = state["stable_abi_data"]
    for node in doctree.findall(addnodes.desc_content):
        par = node.parent
        if par["domain"] != "c":
            continue
        if not par[0].get("ids", None):
            continue
        name = par[0]["ids"][0].removeprefix("c.")
        objtype = par["objtype"]

        # Stable ABI annotation.
        if record := stable_abi_data.get(name):
            if ROLE_TO_OBJECT_TYPE[record.role] != objtype:
                msg = (
                    f"Object type mismatch in limited API annotation for {name}: "
                    f"{ROLE_TO_OBJECT_TYPE[record.role]!r} != {objtype!r}"
                )
                raise ValueError(msg)
            annotation = _stable_abi_annotation(record)
            node.insert(0, annotation)

        # Unstable API annotation.
        if name.startswith("PyUnstable"):
            annotation = _unstable_api_annotation()
            node.insert(0, annotation)

        # Return value annotation
        if objtype != "function":
            continue
        if name not in refcount_data:
            continue
        entry = refcount_data[name]
        if not entry.result_type.endswith("Object*"):
            continue
        annotation = _return_value_annotation(entry.result_refs)
        node.insert(0, annotation)


def _stable_abi_annotation(
    record: StableABIEntry,
    is_corresponding_slot: bool = False,
) -> nodes.emphasis:
    """Create the Stable ABI annotation.

    These have two forms:
      Part of the `Stable ABI <link>`_.
      Part of the `Stable ABI <link>`_ since version X.Y.
    For structs, there's some more info in the message:
      Part of the `Limited API <link>`_ (as an opaque struct).
      Part of the `Stable ABI <link>`_ (including all members).
      Part of the `Limited API <link>`_ (Only some members are part
          of the stable ABI.).
    ... all of which can have "since version X.Y" appended.
    """
    stable_added = record.added
    emph_node = nodes.emphasis('', '', classes=["stableabi"])
    if is_corresponding_slot:
        # See "Type slot annotations" in add_annotations
        ref_node = addnodes.pending_xref(
            "slot ID",
            refdomain="c",
            reftarget="PyType_Slot",
            reftype="type",
            refexplicit="True",
        )
        ref_node += nodes.Text(sphinx_gettext("slot ID"))

        message = sphinx_gettext("The corresponding")
        emph_node += nodes.Text(" " + message + " ")
        emph_node += ref_node
        emph_node += nodes.Text(" ")
        emph_node += nodes.literal(record.name, record.name)
        message = sphinx_gettext("is part of the")
        emph_node += nodes.Text(" " + message + " ")
    else:
        message = sphinx_gettext("Part of the")
        emph_node += nodes.Text(" " + message + " ")
    ref_node = addnodes.pending_xref(
        "Stable ABI",
        refdomain="std",
        reftarget="stable",
        reftype="ref",
        refexplicit="False",
    )
    struct_abi_kind = record.struct_abi_kind
    if struct_abi_kind in {"opaque", "members"}:
        ref_node += nodes.Text(sphinx_gettext("Limited API"))
    else:
        ref_node += nodes.Text(sphinx_gettext("Stable ABI"))
    emph_node += ref_node
    if struct_abi_kind == "opaque":
        emph_node += nodes.Text(" " + sphinx_gettext("(as an opaque struct)"))
    elif struct_abi_kind == "full-abi":
        emph_node += nodes.Text(
            " " + sphinx_gettext("(including all members)")
        )
    if record.ifdef_note:
        emph_node += nodes.Text(f" {record.ifdef_note}")
    if stable_added == "3.2":
        # Stable ABI was introduced in 3.2.
        pass
    else:
        emph_node += nodes.Text(
            " " + sphinx_gettext("since version %s") % stable_added
        )
    emph_node += nodes.Text(".")
    if struct_abi_kind == "members":
        msg = " " + sphinx_gettext(
            "(Only some members are part of the stable ABI.)"
        )
        emph_node += nodes.Text(msg)
    return emph_node


def _unstable_api_annotation() -> nodes.admonition:
    ref_node = addnodes.pending_xref(
        "Unstable API",
        nodes.Text(sphinx_gettext("Unstable API")),
        refdomain="std",
        reftarget="unstable-c-api",
        reftype="ref",
        refexplicit="False",
    )
    emph_node = nodes.emphasis(
        "This is ",
        sphinx_gettext("This is") + " ",
        ref_node,
        nodes.Text(
            sphinx_gettext(
                ". It may change without warning in minor releases."
            )
        ),
    )
    return nodes.admonition(
        "",
        emph_node,
        classes=["unstable-c-api", "warning"],
    )


def _return_value_annotation(result_refs: int | None) -> nodes.emphasis:
    classes = ["refcount"]
    if result_refs is None:
        rc = sphinx_gettext("Return value: Always NULL.")
        classes.append("return_null")
    elif result_refs:
        rc = sphinx_gettext("Return value: New reference.")
        classes.append("return_new_ref")
    else:
        rc = sphinx_gettext("Return value: Borrowed reference.")
        classes.append("return_borrowed_ref")
    return nodes.emphasis(rc, rc, classes=classes)


class LimitedAPIList(SphinxDirective):
    has_content = False
    required_arguments = 0
    optional_arguments = 0
    final_argument_whitespace = True

    def run(self) -> list[nodes.Node]:
        state = self.env.domaindata["c_annotations"]
        content = [
            f"* :c:{record.role}:`{record.name}`"
            for record in state["stable_abi_data"].values()
        ]
        node = nodes.paragraph()
        self.state.nested_parse(StringList(content), 0, node)
        return [node]


class CorrespondingTypeSlot(SphinxDirective):
    """Type slot annotations

    Docs for these are with the corresponding field, for example,
    "Py_tp_repr" is documented under "PyTypeObject.tp_repr", with
    only a stable ABI note mentioning "Py_tp_repr" (and linking to
    docs on how this works).

    If there is no corresponding field, these should be documented as normal
    macros.
    """

    has_content = False

    required_arguments = 1
    optional_arguments = 0

    def run(self) -> list[nodes.Node]:
        name = self.arguments[0]
        state = self.env.domaindata["c_annotations"]
        stable_abi_data = state["stable_abi_data"]

        try:
            record = stable_abi_data[name]
        except LookupError as err:
            raise LookupError(
                f"{name} is not part of stable ABI. "
                + "Document it as `c:macro::` rather than "
                + "`corresponding-type-slot::`."
            ) from err

        annotation = _stable_abi_annotation(record, is_corresponding_slot=True)

        node = nodes.paragraph()
        content = [
            ".. c:namespace:: NULL",
            "",
            ".. c:macro:: " + name,
            "   :no-typesetting:",
        ]
        self.state.nested_parse(StringList(content), 0, node)
        node.insert(0, annotation)
        return [node]


def init_annotations(app: Sphinx) -> None:
    # Using domaindata is a bit hack-ish,
    # but allows storing state without a global variable or closure.
    app.env.domaindata["c_annotations"] = state = {}
    state["refcount_data"] = read_refcount_data(
        Path(app.srcdir, app.config.refcount_file)
    )
    state["stable_abi_data"] = read_stable_abi_data(
        Path(app.srcdir, app.config.stable_abi_file)
    )


def setup(app: Sphinx) -> ExtensionMetadata:
    app.add_config_value("refcount_file", "", "env", types={str})
    app.add_config_value("stable_abi_file", "", "env", types={str})
    app.add_directive("limited-api-list", LimitedAPIList)
    app.add_directive("corresponding-type-slot", CorrespondingTypeSlot)
    app.connect("builder-inited", init_annotations)
    app.connect("doctree-read", add_annotations)

    return {
        "version": "1.0",
        "parallel_read_safe": True,
        "parallel_write_safe": True,
    }
