#!/usr/bin/env python3
"""Regenerate the fleet co-install roster + lock (run after a cornerstone ripple).

Reads the python ``mgf-*`` members from the mgf-standard registry
(``MGF_LIBRARIES.json``, found via ``$MGF_ROOT`` or the federation parent dir),
rewrites ``fleet-coinstall.in``, and resolves it against devpi with ``uv`` into
``fleet-coinstall.lock``. Commit both. The committed lock's ``mgf-common==`` line
is the cornerstone the whole fleet co-installs at; ``test_fleet_coinstall.py``
fails if devpi drifts from it (a leaf lagging) or if the lock goes stale.

Usage:  python tests/fleet/refresh_lock.py
"""

from __future__ import annotations

import json
import os
import re
import shutil
import ssl
import subprocess
import sys
import urllib.request
from pathlib import Path

from mgf.fed._index import devpi_url

_HERE = Path(__file__).resolve().parent
_ROSTER = _HERE / "fleet-coinstall.in"
_LOCK = _HERE / "fleet-coinstall.lock"
_DEVPI = devpi_url()  # §3.4: $DEVPI_URL → the documented default (one resolver)

_ROSTER_HEADER = """\
# Federation co-install roster — every published python mgf-* library.
# Drives tests/fleet/test_fleet_coinstall.py, which asserts the WHOLE fleet
# co-installs at the current mgf-common cornerstone (catches the devpi
# "leaves lag the cornerstone" backfill gap before a human does).
# Regenerate this + fleet-coinstall.lock with:  python tests/fleet/refresh_lock.py
"""

_LOCK_HEADER = (
    "# Committed full-fleet uv lockfile — the resolution of "
    "tests/fleet/fleet-coinstall.in\n"
    "# against devpi. mgf-common== below is the cornerstone the whole fleet "
    "co-installs at.\n"
    "# Generated by tests/fleet/refresh_lock.py (uv pip compile --refresh). "
    "DO NOT hand-edit.\n#\n"
)


def _registry_path() -> Path:
    root = Path(os.environ["MGF_ROOT"]).expanduser() if os.environ.get("MGF_ROOT") else None
    for cand in (root, Path.home() / "PycharmProjects", Path.cwd().parent):
        if cand and (cand / "mgf-standard" / "MGF_LIBRARIES.json").is_file():
            return cand / "mgf-standard" / "MGF_LIBRARIES.json"
    sys.exit("error: mgf-standard/MGF_LIBRARIES.json not found (set MGF_ROOT)")


def _published_on_devpi(name: str) -> bool:
    """True if devpi's simple index serves ≥1 distribution for ``name``.

    The roster is "every *published* python mgf-* library" (see the header). A
    lib that lives in the registry but was never published to devpi — a
    local-only tool such as ``mgf-cloud-web`` (deliberately off-devpi) — must be
    excluded, or the full-fleet ``uv`` resolve fails on a package the index has
    never heard of ("was not found in the package registry"). Ground truth is
    the index itself, so future off-devpi tools are handled without a registry
    flag.
    """
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    url = _DEVPI + f"{name}/"
    try:
        with urllib.request.urlopen(url, context=ctx, timeout=15) as r:  # noqa: S310
            body = r.read().decode("utf-8", "replace")
    except Exception:
        return False
    # a populated simple-index page links at least one sdist/wheel (name-<ver>)
    return bool(re.search(name.replace("-", "[-_]") + r"-\d", body))


def main() -> int:
    uv = shutil.which("uv")
    if uv is None:
        sys.exit("error: uv not on PATH (pip install uv)")
    data = json.loads(_registry_path().read_text(encoding="utf-8"))
    # LIBRARIES only — the `mgf-*` prefix, which this file's own roster header has
    # always claimed ("every published python mgf-* library") while the code did not
    # enforce it. Consumer APPS (hrb-app, vm-vmanager-*, TelePlasma, figrecovery,
    # inthewords) are leaves: nothing depends on them (used_by=0), so co-installing
    # them with each other tests nothing — and two apps pinned to DIFFERENT
    # cornerstone windows make the whole resolution unsatisfiable, which is exactly
    # what happened once hrb-app and vm-vmanager-agent both reached devpi:
    #   hrb-app==0.2.0            needs mgf-common>=0.51,<0.52
    #   vm-vmanager-agent==0.1.0  needs mgf-common>=0.49.2,<0.50   → no overlap
    # The gate exists to catch a LEAF LIBRARY lagging the cornerstone; an app's
    # published pin is REL-10's business, and the REL-13 registry gate already
    # covers it.
    py = sorted(
        lib["repo"]
        for lib in data["libraries"]
        if lib.get("lang") == "python" and lib["repo"].startswith("mgf-")
    )
    libs = [name for name in py if _published_on_devpi(name)]
    excluded = [name for name in py if name not in libs]
    # Guard: if the cornerstone itself looks absent, devpi is unreachable — abort
    # rather than write a garbage (near-empty) roster that would false-red the gate.
    if "mgf-common" not in libs:
        sys.exit("error: devpi unreachable (mgf-common not resolvable) — roster not rewritten")
    if excluded:
        print(f"excluded {len(excluded)} python lib(s) not on devpi: {', '.join(excluded)}")
    _ROSTER.write_text(_ROSTER_HEADER + "\n".join(libs) + "\n", encoding="utf-8")
    print(f"wrote {_ROSTER.name} ({len(libs)} libs)")
    proc = subprocess.run(  # noqa: S603
        [
            uv,
            "pip",
            "compile",
            str(_ROSTER),
            "--index-url",
            _DEVPI,
            "--index-strategy",
            "unsafe-best-match",
            "--refresh",
            "--no-header",
            "--quiet",
        ],
        capture_output=True,
        text=True,
        timeout=300,
    )
    if proc.returncode != 0:
        sys.exit(f"uv pip compile FAILED — fleet does not co-install:\n{proc.stderr}")
    _LOCK.write_text(_LOCK_HEADER + proc.stdout, encoding="utf-8")
    cs = next(
        (
            ln.split("==")[1].strip()
            for ln in proc.stdout.splitlines()
            if ln.strip().startswith("mgf-common==")
        ),
        "?",
    )
    print(f"wrote {_LOCK.name} (cornerstone mgf-common=={cs})")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
