"""R-CAP-ATTEN-WIRE — the `attenuate` wire op: mint a strictly-weaker
sub-capability from the connection's cap.

This is the op #11 (capability-filtered enumeration) and #9 (per-tenant
caps) were waiting on: until now every connection only ever held the
ROOT cap (scope `hw:/**`), so the filter mechanism couldn't be exercised
through a REAL narrow grant. These tests do exactly that — mint a
scope-narrowed sub-cap on the wire, then prove the broker filters
enumeration to the sub-cap's scope.

The cap engine enforces three properties, pinned here end-to-end:
  * narrowing-only (a widen is refused) — `attenuate` can't escalate;
  * the `grant` right is required to delegate;
  * rights narrowing actually restricts what the sub-cap can do.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest

from tests.contract.conftest import rt

if TYPE_CHECKING:
    import socket

pytestmark = pytest.mark.contract


def test_attenuate_narrows_enumeration_to_the_sub_caps_scope(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """The headline property: a scope-narrowed sub-cap filters `list` to
    exactly the in-scope URNs. The test backend always seeds `hw:/test/*`,
    so scoping to `hw:/test/**` yields a deterministic in-scope set; every
    other URN the root can see (pci/usb on a real host) is filtered out."""
    sock, root_cap = raw_broker_with_cap

    root_urns = set(rt(sock, {"op": "list", "scope": "hw:/**", "cap_id": root_cap})["resources"])
    test_urns = {u for u in root_urns if u.startswith("hw:/test/")}
    assert test_urns, "precondition: the broker seeds hw:/test/* URNs"

    att = rt(sock, {"op": "attenuate", "cap_id": root_cap, "scope": "hw:/test/**"})
    assert att.get("ok") is True, f"attenuate should succeed; got {att!r}"
    sub_cap = int(att["cap_id"])
    assert sub_cap != 0 and sub_cap != root_cap

    narrowed = set(rt(sock, {"op": "list", "scope": "hw:/**", "cap_id": sub_cap})["resources"])
    assert narrowed == test_urns, (
        "the sub-cap's list must return EXACTLY the in-scope URNs — every "
        f"out-of-scope URN filtered. root saw {len(root_urns)}, sub saw "
        f"{len(narrowed)}; expected {len(test_urns)} test URNs"
    )


def test_attenuate_refuses_to_widen(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """Attenuation only ever shrinks: narrowing a sub-cap back out to a
    wider scope than its parent is refused (NotPermitted) — the op can't
    be used to escalate."""
    sock, root_cap = raw_broker_with_cap
    sub = rt(sock, {"op": "attenuate", "cap_id": root_cap, "scope": "hw:/test/**"})
    sub_cap = int(sub["cap_id"])
    widen = rt(sock, {"op": "attenuate", "cap_id": sub_cap, "scope": "hw:/**"})
    assert widen.get("ok") is False
    assert widen.get("err") == "NotPermitted", (
        f"widening a sub-cap's scope must be refused; got {widen!r}"
    )


def test_attenuate_requires_the_grant_right(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """Minting sub-caps requires the `grant` right. A sub-cap minted
    WITHOUT grant cannot itself delegate."""
    sock, root_cap = raw_broker_with_cap
    # Narrow rights to observe-only (drops grant). Root has grant; the
    # child does not.
    no_grant = rt(sock, {"op": "attenuate", "cap_id": root_cap, "rights": ["observe"]})
    assert no_grant.get("ok") is True
    no_grant_cap = int(no_grant["cap_id"])
    # The grant-less sub-cap can't attenuate further.
    refused = rt(sock, {"op": "attenuate", "cap_id": no_grant_cap, "scope": "hw:/test/**"})
    assert refused.get("ok") is False
    assert refused.get("err") == "NotPermitted", (
        f"a cap without `grant` must not be able to delegate; got {refused!r}"
    )


def test_attenuate_rights_narrowing_restricts_the_sub_cap(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """Rights narrowing bites end-to-end: an observe-only sub-cap can
    observe-claim but cannot exclusive-claim (the dropped right)."""
    sock, root_cap = raw_broker_with_cap
    sub = rt(sock, {"op": "attenuate", "cap_id": root_cap, "rights": ["observe"]})
    sub_cap = int(sub["cap_id"])

    # Observe-claim is permitted (the one right it kept).
    ok = rt(
        sock,
        {
            "op": "claim",
            "urn": "hw:/test/dev0",
            "mode": "observe",
            "holder": 1,
            "cap_id": sub_cap,
        },
    )
    assert ok.get("ok") is True, f"observe-claim should be permitted; got {ok!r}"

    # Exclusive-claim is refused — the sub-cap dropped claim_exclusive.
    denied = rt(
        sock,
        {
            "op": "claim",
            "urn": "hw:/test/dev1",
            "mode": "exclusive",
            "holder": 1,
            "cap_id": sub_cap,
        },
    )
    assert denied.get("ok") is False
    assert denied.get("err") == "NotPermitted", (
        f"a right dropped by attenuation must be unusable; got {denied!r}"
    )


def test_attenuate_unknown_parent_is_not_permitted(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """An unknown parent cap_id is refused with NotPermitted (uniform with
    the grant/binding refusals — no existence leak about which ids live)."""
    sock, _root_cap = raw_broker_with_cap
    resp = rt(sock, {"op": "attenuate", "cap_id": 0xDEAD_BEEF, "scope": "hw:/test/**"})
    assert resp.get("ok") is False
    assert resp.get("err") == "NotPermitted", (
        f"attenuating an unknown parent must be NotPermitted; got {resp!r}"
    )
