"""Phase-out meta-guards (tier A; phase-outs.md): the rebuild must NOT
carry the retired Supabase/RLS/Toggl surfaces, and the eligibility
predicate must have exactly ONE implementation. These are source-tree
scans — they fail if a future change reintroduces a phased-out pattern.

  T-PHX-007  no RLS in the runtime schema; no Supabase auth client in the
             app runtime (the ONLY Supabase surface is the documented
             read-only migration snapshot source, confined to config +
             the snapshot/harness).
  T-PHX-009  one eligibility predicate (no duplicated conjunction).
  T-PHX-010  the invoice/CC paste blocks are the only sheet-bound exports
             — no 14-column Toggl export path.
"""

from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
APP = ROOT / "app"
ALEMBIC = ROOT / "alembic"


def _py_files(*roots: Path):
    for root in roots:
        for path in root.rglob("*.py"):
            if "__pycache__" in path.parts:
                continue
            yield path


def _read(path: Path) -> str:
    return path.read_text(encoding="utf-8")


# ---------------------------------------------------------------- T-PHX-007


def test_no_rls_in_runtime_schema():
    """No Row-Level-Security policies anywhere in the migrations —
    authorization is service-layer scope(), not Postgres RLS."""
    offenders = []
    for path in _py_files(ALEMBIC):
        text = _read(path).lower()
        if "create policy" in text or "row level security" in text or "enable row level" in text:
            offenders.append(path)
    assert not offenders, f"RLS artifacts in migrations: {offenders}"


def test_no_supabase_auth_client_in_runtime():
    """The runtime app never imports a Supabase client or reads Supabase
    AUTH env. Supabase lives ONLY in the migration snapshot source
    (config.py `supabase_db_*`, read-only) and the harness — never in
    routers, the auth stack, or the domain services."""
    runtime = [
        APP / "routers",
        APP / "services" / "auth",
        APP / "services" / "authz",
        APP / "services" / "reporting",
        APP / "services" / "money",
        APP / "services" / "cc",
    ]
    # `create_client` is deliberately NOT banned — it is a domain term
    # (creating a client party during import resolution), not the Supabase
    # SDK factory. The import/env needles are specific to the SDK/auth.
    banned = (
        "import supabase",
        "from supabase",
        "supabase.create_client",
        "supabase_url",
        "supabase_anon",
        "supabase_service_role",
    )
    offenders = []
    for path in _py_files(*runtime):
        low = _read(path).lower()
        for needle in banned:
            if needle in low:
                offenders.append((path, needle))
    assert not offenders, f"Supabase auth surface in runtime: {offenders}"


def test_app_mints_no_identity_jwt():
    """No JWT-minting: the app verifies id-auth's id_token but never
    encodes its own identity JWT (its session is a signed cookie, not a
    minted JWT). Guard against a `jwt.encode(` creeping into the auth
    stack."""
    offenders = []
    for path in _py_files(APP / "services" / "auth", APP / "routers"):
        text = _read(path)
        if "jwt.encode(" in text or "encode_jwt(" in text:
            offenders.append(path)
    assert not offenders, f"identity-JWT minting found: {offenders}"


# ---------------------------------------------------------------- T-PHX-009


def test_one_eligibility_predicate():
    """`status_condition`/`_eligible`/`_broken` (the eligibility predicate
    and its inverse) are DEFINED in exactly one module — filters.py.
    Every consumer imports from there (status sort included, after the
    M8 dedup)."""
    definers_eligible = []
    definers_broken = []
    definers_condition = []
    for path in _py_files(APP):
        text = _read(path)
        if "def _eligible(" in text:
            definers_eligible.append(path.name)
        if "def _broken(" in text:
            definers_broken.append(path.name)
        if "def status_condition(" in text:
            definers_condition.append(path.name)
    assert definers_eligible == ["filters.py"], definers_eligible
    assert definers_broken == ["filters.py"], definers_broken
    assert definers_condition == ["filters.py"], definers_condition


def test_no_inline_eligibility_conjunction_outside_filters():
    """The 5-field eligibility conjunction (worker & project & description
    & end_at & source_user_email all NOT NULL) appears in exactly one
    file. A re-inlined copy elsewhere is the ADR #018/#021 regression."""
    signature = "worker_party_id.is_not(None)"
    hits = []
    for path in _py_files(APP / "services" / "reporting"):
        text = _read(path)
        # count occurrences of the conjunction's lead term paired with the
        # project term on nearby lines (the sort-rank dedup removed the
        # entries.py copy; filters.py holds the sole definition).
        if signature in text and "project_id.is_not(None)" in text:
            # filters.py legitimately defines it (in _eligible); entries.py
            # must NOT (it uses status_sort_rank / status_case now).
            hits.append(path.name)
    assert hits == ["filters.py"], f"eligibility conjunction duplicated in {hits}"


# ---------------------------------------------------------------- T-PHX-010


def test_no_toggl_export_path():
    """The sheet-bound export surface is the invoice + CC paste blocks
    only (7 tab-separated columns). No module emits the retired 14-column
    Toggl export; 'toggl' never appears as an export/format token in the
    export or router modules (it survives ONLY as a historical
    time_entries.source VALUE handled by the transforms — T-MIG-008)."""
    export_surface = [
        APP / "services" / "money",
        APP / "services" / "cc",
        APP / "routers",
    ]
    offenders = []
    for path in _py_files(*export_surface):
        low = _read(path).lower()
        if "toggl" in low:
            offenders.append(path)
    assert not offenders, f"Toggl reference in the export surface: {offenders}"
