"""R-T1-9A (survivability §3.7, Tier-1 #9, S5) — per-tenant live-lease
ceiling, end-to-end through the real broker dispatch.

The mechanism + the per-uid keying are pinned at the lease-engine layer
in ``core_test.zig`` (which calls ``claimWithCapFromPeer`` directly).
What these wire tests add is proof that the unforgeable SO_PEERCRED uid
actually FLOWS from the broker's accept boundary through dispatch into
``claimImpl`` — i.e. that a single connection (one peer uid) is bounded
at ``MAX_LEASES_PER_UID`` and the broker sheds the over-quota claim with
``Err.Overloaded`` rather than growing the ownership table without limit.

Observe-mode claims never conflict (the lattice permits unlimited
concurrent observers on one URN), so they're the cheapest way to grow
the table — exactly the flood shape S5 bounds. All claims here ride one
socket, so they share the test process's uid; the per-tenant ceiling is
what bites (below the aggregate ceiling).
"""

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

# Must match `MAX_LEASES_PER_UID` in hrb-code/src/core.zig. Kept in sync
# by the matching Zig pin (core_test.zig "per-tenant lease ceiling …").
MAX_LEASES_PER_UID = 64


def test_per_tenant_lease_ceiling_sheds_with_overloaded(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """One connection (one peer uid) can hold up to MAX_LEASES_PER_UID
    live leases; the next claim is shed with Err.Overloaded — back-
    pressure, not a crash, not unbounded growth (S5)."""
    sock, cap_id = raw_broker_with_cap

    # Fill this tenant's quota with non-conflicting observe leases on a
    # single test URN. Each claim returns a distinct lease_id.
    lease_ids: list[int] = []
    for holder in range(1, MAX_LEASES_PER_UID + 1):
        resp = rt(
            sock,
            {
                "op": "claim",
                "urn": "hw:/test/dev0",
                "mode": "observe",
                "holder": holder,
                "cap_id": cap_id,
            },
        )
        assert resp.get("ok") is True, (
            f"claim #{holder} should succeed below the ceiling; got {resp!r}"
        )
        lease_ids.append(int(resp["lease_id"]))

    assert len(set(lease_ids)) == MAX_LEASES_PER_UID, (
        "every in-quota claim must yield a distinct lease id"
    )

    # The over-quota claim is shed — Overloaded, not a crash, not a silent grant.
    over = rt(
        sock,
        {
            "op": "claim",
            "urn": "hw:/test/dev0",
            "mode": "observe",
            "holder": MAX_LEASES_PER_UID + 1,
            "cap_id": cap_id,
        },
    )
    assert over.get("ok") is False, f"over-quota claim must be refused; got {over!r}"
    assert over.get("err") == "Overloaded", (
        f"over-quota claim must shed with Err.Overloaded (S5 back-pressure), "
        f"not {over.get('err')!r}"
    )


def test_releasing_a_lease_frees_the_tenant_quota(
    raw_broker_with_cap: tuple[socket.socket, int],
) -> None:
    """The ceiling tracks LIVE leases: releasing one frees a slot, so
    back-pressure is transient, never a permanent wedge."""
    sock, cap_id = raw_broker_with_cap

    first_lease_id: int | None = None
    for holder in range(1, MAX_LEASES_PER_UID + 1):
        resp = rt(
            sock,
            {
                "op": "claim",
                "urn": "hw:/test/dev0",
                "mode": "observe",
                "holder": holder,
                "cap_id": cap_id,
            },
        )
        assert resp.get("ok") is True
        if first_lease_id is None:
            first_lease_id = int(resp["lease_id"])

    assert first_lease_id is not None
    # At the ceiling.
    over = rt(
        sock,
        {
            "op": "claim",
            "urn": "hw:/test/dev0",
            "mode": "observe",
            "holder": 999,
            "cap_id": cap_id,
        },
    )
    assert over.get("err") == "Overloaded"

    # Release one — the slot reopens.
    rel = rt(
        sock,
        {
            "op": "release",
            "urn": "hw:/test/dev0",
            "lease_id": first_lease_id,
        },
    )
    assert rel.get("ok") is True, f"release should succeed; got {rel!r}"

    reborn = rt(
        sock,
        {
            "op": "claim",
            "urn": "hw:/test/dev0",
            "mode": "observe",
            "holder": 1000,
            "cap_id": cap_id,
        },
    )
    assert reborn.get("ok") is True, f"a freed slot must accept a new claim; got {reborn!r}"
