"""Exception hierarchy for the Influxion SDK."""

from __future__ import annotations


class InfluxionError(Exception):
    """Base exception for all Influxion SDK errors."""


class AuthenticationError(InfluxionError):
    """Raised when the API key is missing, invalid, or rejected (HTTP 401).

    This exception always propagates regardless of ``fail_silently`` because a
    missing or invalid API key is a programming error that should surface immediately.
    """


class APIError(InfluxionError):
    """Raised when the API returns a non-2xx response.

    Carries the HTTP status code and a message extracted from the response body.
    """

    def __init__(self, message: str, *, status_code: int) -> None:
        super().__init__(message)
        self.status_code = status_code
        self.message = message

    def __repr__(self) -> str:
        return (
            f"{type(self).__name__}(status_code={self.status_code!r},"
            f" message={self.message!r})"
        )


class RateLimitError(APIError):
    """Raised when the API returns HTTP 429 and all retry attempts are exhausted."""


class NotFoundError(APIError):
    """Raised when the API returns HTTP 404 (e.g. unknown session_id or artifact_id).

    Not retried — a 404 will not resolve on retry.
    """


class ValidationError(APIError):
    """Raised when the API returns HTTP 422 (field too long, bad enum value, etc.).

    Not retried — the request payload must be corrected.
    """


class ConflictError(APIError):
    """Raised when the API returns HTTP 409 (e.g. session already exists).

    Not retried — the resource conflict must be resolved by the caller.
    """


class NetworkError(InfluxionError):
    """Raised when a transport-level error occurs (connection refused, timeout, etc.).

    Retried with exponential backoff before being raised.
    """
