"""AP-10 / AP-11 contract-sync guard for ``mgf.standard``.

The package has three API-contract artifacts that MUST agree:

  - the runtime ``__all__`` of :mod:`mgf.standard` — the source of truth
    for what is public;
  - ``PUBLIC_API.json`` — the machine-readable pin (``modules`` mapping +
    ``__version__``), resolved by sync sessions over the Codeberg raw API;
  - ``PUBLIC_API.md`` — the human-readable contract list, one row per
    public name with its stability tier (rule **AP-11**) and description.

This is the rule **AP-10** sync test required of every federation sibling
by ``docs/design/federation.md`` (the ``__all__`` ⇄ ``PUBLIC_API`` pin).
It catches the three drift directions:

  1. a name added to ``__all__`` but not to ``PUBLIC_API.json``
     (or vice-versa);
  2. a name in ``PUBLIC_API.json`` with no documented row in
     ``PUBLIC_API.md``;
  3. ``PUBLIC_API.json``'s ``__version__`` drifting from the package's.
"""

from __future__ import annotations

import json
import re
from pathlib import Path

import mgf.standard as ds

_REPO_ROOT = Path(__file__).resolve().parents[2]
_PUBLIC_API_JSON = _REPO_ROOT / "PUBLIC_API.json"
_PUBLIC_API_MD = _REPO_ROOT / "PUBLIC_API.md"


def _json_names() -> set[str]:
    data = json.loads(_PUBLIC_API_JSON.read_text(encoding="utf-8"))
    return set(data["modules"]["mgf.standard"])


def _name_in_md(name: str, md: str) -> bool:
    """True if ``name`` appears in the .md inside a backtick code-span.

    Backtick wrapping is the Markdown-idiomatic way to refer to an
    identifier; requiring it stops a loose prose mention from counting
    as documentation.
    """
    pattern = re.compile(rf"`[^`]*\b{re.escape(name)}\b[^`]*`")
    return bool(pattern.search(md))


class TestPublicApiContractSync:
    def test_all_matches_public_api_json(self) -> None:
        # __all__ is the source of truth; the JSON pin MUST mirror it exactly.
        assert set(ds.__all__) == _json_names()

    def test_public_api_json_version_matches_package(self) -> None:
        data = json.loads(_PUBLIC_API_JSON.read_text(encoding="utf-8"))
        assert data["__version__"] == ds.__version__

    def test_every_public_name_is_documented_in_md(self) -> None:
        md = _PUBLIC_API_MD.read_text(encoding="utf-8")
        missing = sorted(n for n in _json_names() if not _name_in_md(n, md))
        assert not missing, f"names absent from PUBLIC_API.md (rule AP-10): {missing}"
