"""The two ISP-split auth-verifier seams (per ADR-016).

  * :class:`SessionVerifier` — verify a session token (per HTTP request)
    and resolve a principal. Generic over the consumer's principal type
    ``P`` so an app keeps its own (role-typed) principal shape while the
    JWT mechanics live here.
  * :class:`WebhookVerifier` — verify a webhook signature (per provider
    event) and parse a :class:`~mgf.auth.WebhookEvent`.

Both ``@runtime_checkable`` so structural conformance can be asserted
with ``isinstance``. A consumer depends only on the seam it uses — a
session route never sees the webhook surface and vice versa.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Protocol, TypeVar, runtime_checkable

if TYPE_CHECKING:
    from collections.abc import Mapping

    from mgf.auth._events import WebhookEvent

__all__ = ["SessionVerifier", "WebhookVerifier"]

# Covariant: the principal type only appears in return position.
P_co = TypeVar("P_co", covariant=True)


@runtime_checkable
class SessionVerifier(Protocol[P_co]):
    """Verify a session token → the consumer's principal type ``P``."""

    async def verify_session(self, token: str) -> P_co:
        """Return the principal for ``token``.

        Raises :class:`~mgf.auth.InvalidSessionError` for any failure
        (missing / expired / malformed / signature / issuer / resolver).
        """
        ...


@runtime_checkable
class WebhookVerifier(Protocol):
    """Verify a webhook signature → a :class:`~mgf.auth.WebhookEvent`."""

    async def verify_webhook(self, headers: Mapping[str, str], body: bytes) -> WebhookEvent:
        """Verify ``(headers, body)`` and parse the event.

        Raises :class:`~mgf.auth.InvalidWebhookSignatureError` when any
        component of the signature check fails.
        """
        ...
