"""The platform scope convention — matcher unit tests + drift guard (#43).

scopes.py is VENDORED byte-for-byte from the platform canonical
(nechapi/_platform/scopes.py) so the gateway and this service enforce the
identical rule. The drift guard fails if the two ever diverge.
"""
from pathlib import Path

import scopes


# ── required-scope derivation (access tracks the URL by construction) ──────────
def test_required_for_derives_from_path():
    assert scopes.required_for("audio", "/analyze/emotion") == "api:audio:analyze:emotion"
    assert scopes.required_for("audio", "/grade") == "api:audio:grade"
    assert scopes.required_for("audio", "/") == "api:audio"
    assert scopes.required_for("geo", "/reverse") == "api:geo:reverse"


# ── matching: wildcards open subtrees; non-wildcards are exact ─────────────────
def test_wildcards_open_subtrees():
    req = "api:audio:analyze:emotion"
    for g in ("*", "api:*", "api:audio:*", "api:audio:analyze:*", "api:audio:analyze:emotion"):
        assert scopes.matches(g, req), g


def test_non_wildcard_is_exact_not_prefix():
    # granting exactly api:audio does NOT grant its children — only api:audio:* does
    assert not scopes.matches("api:audio", "api:audio:grade")
    assert scopes.matches("api:audio", "api:audio")


def test_sibling_and_realm_isolation():
    assert not scopes.matches("api:audio:features", "api:audio:grade")
    assert not scopes.matches("api:*", "admin:tenants")      # api:* never grants admin
    assert not scopes.matches("admin:*", "api:audio:grade")
    assert scopes.matches("*", "admin:anything")             # bare * is superadmin


def test_match_any():
    granted = {"api:audio:features", "api:audio:grade"}
    assert scopes.match_any(granted, "api:audio:grade")
    assert not scopes.match_any(granted, "api:audio:analyze:emotion")


# ── validation (the CLI rejects malformed grants on mint) ─────────────────────
def test_validate():
    for ok in ("*", "api:*", "api:audio:*", "api:audio:analyze:emotion", "admin:*"):
        assert scopes.validate(ok), ok
    for bad in ("", "api::emotion", "api:*:emotion", "api:audio:"):
        assert not scopes.validate(bad), bad


# ── drift guard: vendored copy must equal the platform canonical ──────────────
def test_vendored_scopes_matches_platform_canonical():
    canonical = Path.home() / "Work" / "nechapi" / "_platform" / "scopes.py"
    if not canonical.exists():
        import pytest
        pytest.skip("platform canonical not present (CI/container) — dev-only guard")
    here = Path(scopes.__file__)
    assert here.read_text() == canonical.read_text(), (
        "armada/api/scopes.py drifted from nechapi/_platform/scopes.py — re-vendor it"
    )
