# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-of-a-delegated-capability-token-appear-valid-at-every-hop-yet-grant-no-authority-at-the-leaf.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-of-a-delegated-capability-token-appear-valid-at-every-hop-yet-grant-no-authority-at-the-leaf.warrant.json
# Markdown SHA-256:   34e7be35942f2a3eca211c0b6f75d877b71a819bb26ecec1fe3c0db940621820
# Code AST SHA-256:   004c9bdf64f7621e4831e89b413dd7d4499731b6a62d3644adfcb02f7019e805
# Verified Classes:   EmptyEffectiveCapabilityError, HopConstraint
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field


class EmptyEffectiveCapabilityError(RuntimeError):
    """Raised when a structurally valid delegated token yields an empty effective capability set."""

    def __init__(self, chain_id: str, ceiling: int, floor: int):
        self.chain_id = chain_id
        self.ceiling = ceiling
        self.floor = floor
        super().__init__(
            f"chain {chain_id!r}: structural validation passed but effective set is empty "
            f"(delegation_depth ceiling {ceiling} from upstream hop, floor {floor} required at leaf)"
        )


@dataclass
class HopConstraint:
    delegation_depth_ceiling: int | None = None
    delegation_depth_floor: int | None = None
    allowed_actions: set[str] = field(default_factory=set)


def resolve_effective_depth(chain_id: str, hops: list[HopConstraint]) -> int:
    """Intersect all per-hop depth constraints; raise if the conjunction is empty."""
    ceilings = [h.delegation_depth_ceiling for h in hops if h.delegation_depth_ceiling is not None]
    floors = [h.delegation_depth_floor for h in hops if h.delegation_depth_floor is not None]

    ceiling = min(ceilings) if ceilings else 2**31 - 1
    floor = max(floors) if floors else 0

    if floor > ceiling:
        raise EmptyEffectiveCapabilityError(chain_id, ceiling, floor)
    return ceiling


def verify_leaf_action(chain_id: str, hops: list[HopConstraint], action: str) -> bool:
    effective_depth = resolve_effective_depth(chain_id, hops)
    actions = set.intersection(*(h.allowed_actions for h in hops)) if hops else set()
    if action not in actions:
        raise EmptyEffectiveCapabilityError(chain_id, effective_depth, effective_depth)
    return True
