"""mgf-auth typed errors.

Both subclass ``mgf.common.exceptions.HttpUnauthorizedError`` so they
carry ``http_status = 401`` (a consumer's exception-translation
middleware turns a bad session / webhook signature into a 401) and root
at the federation ``AppError`` (rule EH-01).
"""

from __future__ import annotations

from mgf.common.exceptions import HttpUnauthorizedError

__all__ = ["InvalidSessionError", "InvalidWebhookSignatureError"]


class InvalidSessionError(HttpUnauthorizedError):
    """A session token failed verification.

    Raised for any failure: missing / expired / malformed JWT, signature
    mismatch, issuer mismatch, or a resolver rejection. The message never
    leaks the token (it's sensitive); forensic detail goes to logs.
    """

    def __init__(self, reason: str) -> None:
        self.reason = reason  # EH-08: machine-readable field (route on this, not the message)
        super().__init__(f"invalid session: {reason}")


class InvalidWebhookSignatureError(HttpUnauthorizedError):
    """An inbound webhook didn't carry a verifiable signature.

    Raised when the Svix signature header is missing, the timestamp is
    outside the replay window, the HMAC doesn't match, or the body isn't
    parseable JSON. Consumers return 401 (Svix/Clerk treat 4xx as
    permanent — stops the retry storm on a misconfigured secret).
    """

    def __init__(self, reason: str) -> None:
        self.reason = reason  # EH-08: machine-readable field
        super().__init__(reason)
