"""Retry logic with exponential backoff."""

from typing import Callable, TypeVar

from tenacity import (
    retry,
    retry_if_exception_type,
    stop_after_attempt,
    wait_exponential,
)

from kamimind_storage.constants import (
    DEFAULT_MAX_RETRIES,
    RETRY_BACKOFF_FACTOR,
    RETRY_MAX_DELAY,
)
from kamimind_storage.exceptions import RetryableError

T = TypeVar("T")


def create_retry_decorator(
    max_retries: int = DEFAULT_MAX_RETRIES,
    backoff_factor: int = RETRY_BACKOFF_FACTOR,
    max_delay: int = RETRY_MAX_DELAY,
) -> Callable[[Callable[..., T]], Callable[..., T]]:
    """Create a retry decorator with exponential backoff.

    Args:
        max_retries: Maximum number of retry attempts.
        backoff_factor: Multiplier for exponential backoff.
        max_delay: Maximum delay between retries in seconds.

    Returns:
        A configured retry decorator.
    """
    return retry(
        retry=retry_if_exception_type(RetryableError),
        stop=stop_after_attempt(max_retries + 1),
        wait=wait_exponential(multiplier=backoff_factor, max=max_delay),
        reraise=True,
    )


def is_retryable_status_code(status_code: int) -> bool:
    """Check if an HTTP status code is retryable.

    Args:
        status_code: HTTP status code.

    Returns:
        True if the status code indicates a retryable error.
    """
    return status_code in {408, 429, 500, 502, 503, 504}
