"""Pin: ``PUBLIC_API.json`` MUST match the generator's output.

v0.4 Phase G6. The JSON is the machine-readable companion to
``PUBLIC_API.md``; consumer CI scripts grep/parse it to verify
their pinned imports survive an upgrade. Drift between the
generator and the checked-in JSON would silently invalidate
those scripts — this pin catches it.

When this test fails:
    Run ``uv run python tools/generate_public_api_json.py`` to
    regenerate, then commit the updated ``PUBLIC_API.json``.
"""

from __future__ import annotations

import json
from pathlib import Path

from tools.generate_public_api_json import build_payload  # type: ignore[import-not-found]

PUBLIC_API_JSON_PATH = Path(__file__).resolve().parent.parent.parent / "PUBLIC_API.json"


def test_public_api_json_exists() -> None:
    """Sanity: the file is checked in."""
    assert PUBLIC_API_JSON_PATH.exists(), (
        f"PUBLIC_API.json missing at {PUBLIC_API_JSON_PATH}. "
        f"Run `uv run python tools/generate_public_api_json.py`."
    )


def test_public_api_json_matches_generator_output() -> None:
    """Pin: regenerating the JSON MUST produce the file on disk."""
    actual = json.loads(PUBLIC_API_JSON_PATH.read_text(encoding="utf-8"))
    expected = build_payload()
    assert actual == expected, (
        "PUBLIC_API.json is out of sync with the live __all__ of "
        "the public modules. Regenerate with: "
        "`uv run python tools/generate_public_api_json.py` and "
        "commit the result."
    )


def test_public_api_json_total_matches_actual_count() -> None:
    """Sanity: the metadata count agrees with the listed names."""
    payload = json.loads(PUBLIC_API_JSON_PATH.read_text(encoding="utf-8"))
    actual_total = sum(len(names) for names in payload["modules"].values())
    assert actual_total == payload["__generated_total_names"], (
        f"Metadata mismatch: __generated_total_names = "
        f"{payload['__generated_total_names']} but the modules dict "
        f"has {actual_total} names."
    )
