"""PUBLIC_API.json pin (DOC-08): the committed companion MUST match the live ``__all__``."""

from __future__ import annotations

import json
import re
import tomllib
from pathlib import Path

import pytest

import mgf.fed

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


def test_public_api_json_matches_all() -> None:
    data = json.loads(_PUBLIC_API_JSON.read_text(encoding="utf-8"))
    live = [*sorted(n for n in mgf.fed.__all__ if n != "__version__"), "__version__"]
    assert sorted(data["modules"]["mgf.fed"]) == sorted(live), (
        "PUBLIC_API.json is out of sync with mgf.fed.__all__ — "
        "regenerate: `python tools/generate_public_api_json.py`"
    )


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


# ---------------------------------------------------------------------------
# PAPER-167 — `uv.lock` records this package's OWN version, and nothing compared
# it. It shipped two releases stale (v0.25.3 and v0.25.4 both carried a lock
# saying 0.25.2) under green CI.
#
# Nothing caught it because the fleet's uv.lock discipline is about `--frozen`
# (WF-14 / CIR-04 / PAPER-125), and `--frozen` means "do not update the lock" —
# it makes a stale lock QUIETER, not louder. `release_currency()` misses it too:
# its model of installable content is `src/` + `pyproject.toml`.
#
# This sits next to the PUBLIC_API.json pin because that is the working
# precedent: same class of defect, same repo, already caught by a pin test.
# ---------------------------------------------------------------------------

_PYPROJECT = Path(__file__).resolve().parents[2] / "pyproject.toml"
_UV_LOCK = Path(__file__).resolve().parents[2] / "uv.lock"


def _lock_self_version(text: str, name: str) -> str | None:
    """The version `uv.lock` records for the editable package `name`."""
    for block in text.split("[[package]]"):
        if re.search(rf'^name\s*=\s*"{re.escape(name)}"\s*$', block, re.MULTILINE):
            m = re.search(r'^version\s*=\s*"([^"]+)"\s*$', block, re.MULTILINE)
            return m.group(1) if m else None
    return None


def test_uv_lock_self_version_matches_pyproject() -> None:
    if not _UV_LOCK.is_file():  # pragma: no cover — a checkout without a lock
        pytest.skip("no uv.lock in this checkout")
    proj = tomllib.loads(_PYPROJECT.read_text(encoding="utf-8"))
    name = proj["project"]["name"]
    declared = proj["project"]["version"]
    locked = _lock_self_version(_UV_LOCK.read_text(encoding="utf-8"), name)
    assert locked is not None, f"uv.lock has no [[package]] entry for {name!r}"
    assert locked == declared, (
        f"uv.lock records {name} {locked!r} but pyproject.toml declares {declared!r} — "
        "regenerate with `uv lock`. A lockfile that misnames the package it locks "
        "shipped two releases this way under green CI (PAPER-167)."
    )
