"""Unit mirror for ``mgf.fed._roster`` (TS-01).

Focuses on the roster module's own surface — federation-root resolution, the
:class:`Member` dataclass properties, and registry loading/error handling.
(The wave-ordering integration is also exercised via ``test_status.py``.)
"""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from mgf.fed._roster import Member, federation_root, load_registry, members


def _write_registry(root: Path, reg: dict[str, object]) -> Path:
    (root / "mgf-standard").mkdir(parents=True, exist_ok=True)
    path = root / "mgf-standard" / "MGF_LIBRARIES.json"
    path.write_text(json.dumps(reg), encoding="utf-8")
    return path


def test_federation_root_prefers_env(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setenv("MGF_ROOT", str(tmp_path))
    assert federation_root() == tmp_path


def test_federation_root_falls_back_to_cwd_when_no_default(
    tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
    monkeypatch.delenv("MGF_ROOT", raising=False)
    monkeypatch.setattr(Path, "home", classmethod(lambda cls: tmp_path / "nonexistent-home"))
    monkeypatch.chdir(tmp_path)
    assert federation_root() == Path.cwd()


def test_member_properties() -> None:
    m = Member(
        repo="mgf-foo",
        lang="python",
        registry_version="1.2.3",
        extras=("dev", "standards"),
        root=Path("/srv/fleet"),
    )
    assert m.repo_dir == Path("/srv/fleet/mgf-foo")
    assert m.has_standards_extra is True
    assert Member(repo="mgf-bar", lang="python", registry_version="0").has_standards_extra is False


def test_load_registry_missing_raises(tmp_path: Path) -> None:
    with pytest.raises(FileNotFoundError, match="registry not found"):
        load_registry(tmp_path)


def test_members_sorts_unwaved_repos_last(tmp_path: Path) -> None:
    _write_registry(
        tmp_path,
        {
            "release_waves": [["mgf-common"]],
            "libraries": [
                {"repo": "mgf-orphan", "lang": "zig", "version": "0.1.0"},
                {"repo": "mgf-common", "lang": "python", "version": "0.47.0"},
            ],
        },
    )
    ms = members(tmp_path)
    assert [m.repo for m in ms] == ["mgf-common", "mgf-orphan"]
    assert ms[0].wave == 0
    assert ms[1].wave == -1  # not in any wave → sorts to the end
