from __future__ import annotations

from dataclasses import dataclass
from typing import Any


PilotStatusErrorBody = Any


class PilotStatusError(Exception):
    pass


@dataclass(frozen=True)
class PilotStatusHttpError(PilotStatusError):
    message: str
    status: int
    method: str
    url: str
    headers: dict[str, str]
    body: PilotStatusErrorBody | None = None
    raw_body: str | None = None

    def __str__(self) -> str:
        return self.message


class AuthenticationError(PilotStatusHttpError):
    pass


class ValidationError(PilotStatusHttpError):
    pass


class ForbiddenError(PilotStatusHttpError):
    pass


class NotFoundError(PilotStatusHttpError):
    pass


class ConflictError(PilotStatusHttpError):
    pass


class RateLimitError(PilotStatusHttpError):
    pass


class ServerError(PilotStatusHttpError):
    pass


def create_http_error(
    *,
    message: str,
    status: int,
    method: str,
    url: str,
    headers: dict[str, str],
    body: PilotStatusErrorBody | None = None,
    raw_body: str | None = None,
) -> PilotStatusHttpError:
    if status == 401:
        return AuthenticationError(message, status, method, url, headers, body, raw_body)
    if status == 400:
        return ValidationError(message, status, method, url, headers, body, raw_body)
    if status == 403:
        return ForbiddenError(message, status, method, url, headers, body, raw_body)
    if status == 404:
        return NotFoundError(message, status, method, url, headers, body, raw_body)
    if status == 409:
        return ConflictError(message, status, method, url, headers, body, raw_body)
    if status == 429:
        return RateLimitError(message, status, method, url, headers, body, raw_body)
    if status >= 500:
        return ServerError(message, status, method, url, headers, body, raw_body)
    return PilotStatusHttpError(message, status, method, url, headers, body, raw_body)

