"""Typed failures raised by the Spotify adapter."""

from app.ports.protocols import CatalogQuotaExhaustedError


class SpotifyError(Exception):
    """Base class for Spotify adapter failures."""


class SpotifyAuthenticationError(SpotifyError):
    """Spotify rejected authentication or token refresh."""


class SpotifyRateLimitedError(SpotifyError):
    """Spotify rate limited a request that could not be retried."""

    def __init__(self, retry_after_seconds: float | None, reason: str | None = None) -> None:
        """Record Spotify's requested delay without exposing request data."""
        super().__init__("Spotify rate limit exceeded")
        self.retry_after_seconds = retry_after_seconds
        self.reason = reason


class SpotifyQuotaExhaustedError(SpotifyRateLimitedError, CatalogQuotaExhaustedError):
    """Spotify rejected a request because the application quota is exhausted."""


class SpotifyUnavailableError(SpotifyError):
    """Spotify returned a server-side failure."""

    def __init__(self, status_code: int, message: str | None = None) -> None:
        """Record safe details from a Spotify server failure."""
        generic_message = f"Spotify is unavailable with status {status_code}"
        super().__init__(message if message is not None else generic_message)
        self.status_code = status_code
        self.message = message


class SpotifyRequestError(SpotifyError):
    """Spotify rejected a non-authenticated API request."""

    def __init__(self, status_code: int, message: str | None = None) -> None:
        """Record safe details from a rejected Spotify request."""
        generic_message = f"Spotify request failed with status {status_code}"
        super().__init__(message if message is not None else generic_message)
        self.status_code = status_code
        self.message = message
