"""Exception hierarchy shared across Context Platform tooling."""


class SharedError(Exception):
    """Base exception for shared utilities."""


class ConfigError(SharedError):
    """Raised when configuration is invalid or incomplete."""


class BackendRequestError(SharedError):
    """Raised when the backend API reports an error."""

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


class AuthenticationError(BackendRequestError):
    """Raised for authentication failures."""


class NotFoundError(BackendRequestError):
    """Raised when a requested resource cannot be found.

    Attributes:
        resource_type: Type of resource not found (e.g., "project", "item", "file").
        resource_key: Key/identifier of the missing resource.
    """

    def __init__(
        self,
        message: str,
        *,
        resource_type: str | None = None,
        resource_key: str | None = None,
        status_code: int | None = None,
        request_id: str | None = None,
        response_body: str | None = None,
        request_url: str | None = None,
    ) -> None:
        super().__init__(
            message,
            status_code=status_code,
            request_id=request_id,
            response_body=response_body,
            request_url=request_url,
        )
        self.resource_type = resource_type
        self.resource_key = resource_key


class ValidationFailure(BackendRequestError):
    """Raised for 4xx validation errors."""


class ConflictError(BackendRequestError):
    """Raised when a conflict occurs (e.g., duplicate key, non-empty project)."""


class PreconditionFailedError(BackendRequestError):
    """Raised when ETag precondition fails."""
