"""
MemoraLabs SDK exceptions.

All errors raised by the MemoraLabs client are subclasses of MemoraLabsError.
HTTP status codes are mapped to specific exception subclasses so callers can
handle them with targeted except clauses.
"""
from __future__ import annotations


class MemoraLabsError(Exception):
    """Base exception for all MemoraLabs SDK errors.

    Attributes:
        status_code: HTTP status code returned by the API (or 0 for network errors).
        error_code:  Machine-readable error code from the API response body, or
                     a synthetic code for client-side errors.
        message:     Human-readable description of the error.
    """

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

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


class AuthError(MemoraLabsError):
    """Raised on HTTP 401 — missing or invalid API key."""

    def __init__(self, message: str = "Invalid or missing API key") -> None:
        super().__init__(message, status_code=401, error_code="UNAUTHORIZED")


class PlanLimitError(MemoraLabsError):
    """Raised on HTTP 402 — plan limit exceeded.

    Attributes:
        upgrade_url: URL for upgrading to a higher plan, if provided by the API.
    """

    def __init__(
        self,
        message: str = "Plan limit exceeded",
        *,
        upgrade_url: str | None = None,
    ) -> None:
        super().__init__(message, status_code=402, error_code="PLAN_LIMIT_EXCEEDED")
        self.upgrade_url = upgrade_url


class NotFoundError(MemoraLabsError):
    """Raised on HTTP 404 — memory or resource not found."""

    def __init__(self, message: str = "Resource not found") -> None:
        super().__init__(message, status_code=404, error_code="NOT_FOUND")


class RateLimitError(MemoraLabsError):
    """Raised on HTTP 429 — too many requests."""

    def __init__(self, message: str = "Rate limit exceeded") -> None:
        super().__init__(message, status_code=429, error_code="RATE_LIMITED")


class ValidationError(MemoraLabsError):
    """Raised on HTTP 422 — request validation failed."""

    def __init__(self, message: str = "Request validation failed") -> None:
        super().__init__(message, status_code=422, error_code="VALIDATION_ERROR")
