"""Retry logic for LLM API calls."""

from __future__ import annotations

import httpx
from tenacity import (
    retry,
    retry_if_exception,
    stop_after_attempt,
    wait_exponential_jitter,
)


def _is_retryable(exc: BaseException) -> bool:
    """Return True for transient / rate-limit errors that should be retried."""
    # httpx transport errors (connection reset, timeout, etc.)
    if isinstance(exc, (httpx.ConnectError, httpx.ReadTimeout, httpx.WriteTimeout, httpx.PoolTimeout)):
        return True

    # HTTP status-based errors from provider SDKs
    status = getattr(exc, "status_code", None) or getattr(exc, "status", None)
    if status is not None:
        return status in (429, 500, 502, 503, 529)

    return False


llm_retry = retry(
    retry=retry_if_exception(_is_retryable),
    wait=wait_exponential_jitter(initial=1, max=30, jitter=2),
    stop=stop_after_attempt(4),
    reraise=True,
)
"""Decorator: retries on rate-limit (429) and transient server errors (5xx).

Uses exponential backoff with jitter. Max 4 attempts (1 initial + 3 retries).
Non-retryable errors (400, 401, 403, 404, etc.) are raised immediately.
"""
