"""Error types raised by :mod:`mgf.http`.

Wraps ``httpx`` errors into the ``mgf.common.exceptions`` hierarchy so
the standard CLI exit-code translator + ``except AppError:`` patterns
just work.

This module is private — consumers import from
:mod:`mgf.http.exceptions` (the stable public re-export point per the
federation pattern).
"""

from __future__ import annotations

from mgf.common.exceptions import OperationError


def _actionable_hint(cause_summary: str) -> str:
    """EH-09 — a short, actionable next step keyed on the failure category."""
    c = cause_summary.lower()
    if "timeout" in c:
        return "increase the per-request `timeout=` or check the endpoint's responsiveness"
    if "connect" in c or "network" in c:
        return "verify the host/port, DNS, and network connectivity"
    if "5" in c and ("0" in c or "xx" in c or "status" in c):
        return "the server is failing (5xx); check provider status or retry later"
    if "429" in c or "rate" in c:
        return "you are being rate-limited; back off or honour Retry-After"
    return "inspect the chained `__cause__` for the underlying transport error"


class HttpTransportError(OperationError):
    """Raised when an HTTP request fails at the transport layer.

    Distinct from a 4xx/5xx response — those are NOT errors at this
    layer; the consumer's check chain (or ``response.raise_for_status``)
    decides whether they're problems. This is "the response never
    arrived" or "the response arrived but couldn't be parsed for
    any reason that's our problem, not the provider's."

    Carries:

      - ``url``: the URL that was attempted (after redirects, when known).
      - ``cause_summary``: a short categorisation
        (``"timeout after 30s"``, ``"connect refused"``, ...) for
        log + OTel attribution.
      - ``attempts``: how many retries were attempted before giving up.

    The original ``httpx`` exception is preserved as ``__cause__``.

    Renamed from ``HttpClientError`` at the v0.29 / mgf-http v0.1
    federation cutover to disambiguate from
    :class:`mgf.common.exceptions.HttpClientError` (the HTTP-01
    hierarchy node for 4xx-class responses, which stays in
    mgf-common). The old name ``HttpClientError`` is GONE — no
    deprecation alias; consumers rename in lock-step.
    """

    def __init__(
        self,
        *,
        url: str,
        cause_summary: str,
        attempts: int,
    ) -> None:
        self.url = url
        self.cause_summary = cause_summary
        self.attempts = attempts
        super().__init__(
            f"HTTP request failed for {url} after {attempts} attempt"
            f"{'s' if attempts != 1 else ''}: {cause_summary}. "
            f"Hint: {_actionable_hint(cause_summary)}"
        )


__all__ = ["HttpTransportError"]
