"""Exception hierarchy for minimal_activitypub."""

from whenever import Instant


class ActivityPubError(Exception):
    """Base class for all mastodon exceptions."""

    def __init__(  # noqa: PLR0913
        self,
        status_code: int | None = None,
        reason_phrase: str | None = None,
        message: str | None = None,
        *,
        endpoint: str | None = None,
        method: str | None = None,
        request_id: str | None = None,
        response_text: str | None = None,
    ) -> None:
        """Initialise with optional context for debugging.

        :param status_code: HTTP status code (e.g. 401)
        :param reason_phrase: HTTP reason phrase (e.g. "Unauthorized")
        :param message: Human-readable error message extracted from the API response
        :param endpoint: URL that was requested (includes query parameters)
        :param method: HTTP method used (e.g. "GET", "POST")
        :param request_id: Server-assigned request ID from ``X-Request-Id`` response header, if present
        :param response_text: Raw response body, truncated to 500 characters. Request body
            parameters are intentionally not captured to avoid logging sensitive content
            (access tokens, user-authored text, etc.).
        """
        self.status_code = status_code
        self.reason_phrase = reason_phrase
        self.message = message
        self.endpoint = endpoint
        self.method = method
        self.request_id = request_id
        self.response_text = response_text
        self.occurred_at: Instant = Instant.now()
        parts = []
        if status_code is not None:
            parts.append(str(status_code))
        if reason_phrase:
            parts.append(reason_phrase)
        if endpoint:
            parts.append(f"at {endpoint}")
        if message:
            parts.append(f"\u2014 {message}")
        super().__init__(" ".join(parts) if parts else "")


class NetworkError(ActivityPubError):
    """`NetworkError` is a subclass of `ActivityPubError` that is raised when
    there is a network error.
    """

    pass


class ApiError(ActivityPubError):
    """`ApiError` is a subclass of `ActivityPubError` that is raised when there
    is an API error.
    """

    pass


class ClientError(ActivityPubError):
    """`ClientError` is a subclass of `ActivityPubError` that is raised when
    there is a client error.
    """

    pass


class UnauthorizedError(ClientError):
    """`UnauthorizedError` is a subclass of `ClientError` that is raised when
    the user represented by the auth_token is not authorized to perform a
    certain action.
    """

    pass


class ForbiddenError(ClientError):
    """`ForbiddenError` is a subclass of `ClientError` that is raised when the
    user represented by the auth_token is forbidden to perform a certain
    action.
    """

    pass


class NotFoundError(ClientError):
    """`NotFoundError` is a subclass of `ClientError` that is raised when an
    object for an action cannot be found.
    """

    pass


class ConflictError(ClientError):
    """`ConflictError` is a subclass of `ClientError` that is raised when there
    is a conflict with performing an action.
    """

    pass


class GoneError(ClientError):
    """`GoneError` is a subclass of `ClientError` that is raised when an object
    for an action has gone / been deleted.
    """

    pass


class UnprocessedError(ClientError):
    """`UnprocessedError` is a subclass of `ClientError` that is raised when an
    action cannot be processed.
    """

    pass


class RatelimitError(ClientError):
    """`RatelimitError` is a subclass of `ClientError` that is raised when
    we've reached a limit of number of actions performed quickly.
    """

    pass


class ServerError(ActivityPubError):
    """`ServerError` is a subclass of `ActivityPubError` that is raised when
    the server / instance encountered an error.
    """

    pass
