# src/veritell_langchain/errors.py

from __future__ import annotations

from dataclasses import dataclass
from typing import Optional


@dataclass
class VeritellError(Exception):
    message: str = ""
    status: Optional[int] = None
    error: Optional[str] = None
    # Allow http layer to pass these through for any error type.
    upgrade_url: Optional[str] = None
    retry_after_seconds: Optional[float] = None

    def __str__(self) -> str:  # pragma: no cover
        base = self.message or self.error or self.__class__.__name__
        if self.status is not None:
            return f"{base} (status={self.status})"
        return base


@dataclass
class VeritellValidationError(VeritellError):
    """Raised when validation of input or schema fails."""
    pass


@dataclass
class VeritellAuthError(VeritellError):
    """Authentication/authorization failed."""
    pass


@dataclass
class VeritellRequestError(VeritellError):
    """4xx request errors (excluding auth/rate-limit)."""
    pass


@dataclass
class VeritellServerError(VeritellError):
    """5xx server errors."""
    pass


@dataclass
class RateLimitedError(VeritellError):
    """429 and plan-limit errors."""
    pass


@dataclass
class ServiceUnavailableError(VeritellError):
    """503 and transient maintenance errors."""
    pass


@dataclass
class VeritellTimeoutError(VeritellError):
    """Timeout while calling Veritell."""
    pass


@dataclass
class VeritellConnectionError(VeritellError):
    """Network / connection failures."""
    pass


@dataclass
class VeritellAPIError(Exception):
    """Raised when the Veritell API returns a non-2xx response."""

    status_code: int
    message: str = ""

    def __str__(self) -> str:  # pragma: no cover
        return self.message or f"API error (status={self.status_code})"


VeritellRateLimitedError = RateLimitedError
VeritellServiceUnavailableError = ServiceUnavailableError
VeritellLimitError = RateLimitedError

__all__ = [
    "VeritellError",
    "VeritellAuthError",
    "VeritellRequestError",
    "VeritellServerError",
    "RateLimitedError",
    "ServiceUnavailableError",
    "VeritellTimeoutError",
    "VeritellAPIError",
    "VeritellConnectionError",
    "VeritellValidationError",
    "VeritellRateLimitedError",
    "VeritellServiceUnavailableError",
    "VeritellLimitError",
]
