# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-happens-when-an-instance-presents-a-delegated-capability-token-whose-delegation-chain-contains-a-revoked-intermediate-but-a-still-valid-leaf-sign.md
# Remnant Warrant:    https://corpusfetch.com/c/what-happens-when-an-instance-presents-a-delegated-capability-token-whose-delegation-chain-contains-a-revoked-intermediate-but-a-still-valid-leaf-sign.warrant.json
# Markdown SHA-256:   a3aa47f02bd3318f73f97e28a7c6f7c796160020cdad4d983c96cc490495901a
# Code AST SHA-256:   c1013b892e432fd8986b99d918649ae7f99d152929c8ef4717106119ccdb1093
# Verified Classes:   DelegationChainRevoked, Credential
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import hashlib
from dataclasses import dataclass
from typing import Optional


class DelegationChainRevoked(RuntimeError):
    """Raised when a leaf capability token's delegation chain contains a revoked ancestor."""
    pass


@dataclass(frozen=True)
class Credential:
    credential_id: str
    delegator_id: Optional[str]  # None for root
    issued_at: int
    signature_valid: bool  # signature over the delegation edge / attenuation predicate


def _revocation_status(credential_id: str, revocation_index: dict[str, int]) -> bool:
    """Return True if the credential is revoked as of now. Missing entry => not revoked."""
    return credential_id in revocation_index


def verify_leaf_authorization(
    leaf: Credential,
    chain: dict[str, Credential],
    revocation_index: dict[str, int],
    require_ancestor_status: bool = True,
) -> bool:
    """
    Verify a leaf capability token by walking the full delegation chain.

    The leaf signature alone is NOT sufficient: an intermediate ancestor may be
    revoked while the leaf signature remains intact. Fail closed if an ancestor's
    revocation status cannot be resolved and require_ancestor_status is set.
    """
    if not leaf.signature_valid:
        raise DelegationChainRevoked(
            f"leaf {leaf.credential_id}: signature invalid"
        )

    cursor: Optional[Credential] = leaf
    visited: set[str] = set()
    while cursor is not None:
        if cursor.credential_id in visited:
            raise DelegationChainRevoked(
                f"cycle detected at {cursor.credential_id}"
            )
        visited.add(cursor.credential_id)

        # Check revocation as of NOW for every hop, not just the leaf.
        if _revocation_status(cursor.credential_id, revocation_index):
            raise DelegationChainRevoked(
                f"delegation chain revoked at ancestor {cursor.credential_id} "
                f"(leaf {leaf.credential_id})"
            )

        if cursor.delegator_id is None:
            break  # reached root

        parent = chain.get(cursor.delegator_id)
        if parent is None:
            if require_ancestor_status:
                raise DelegationChainRevoked(
                    f"cannot resolve ancestor {cursor.delegator_id} for "
                    f"leaf {leaf.credential_id}; failing closed"
                )
            break
        cursor = parent

    return True
