from dataclasses import dataclass, field
from typing import List, Optional, Set

@dataclass
class RetryConfig:
    """
    Configuration for the invoke wrapper.

    Attributes:
        max_retries: The maximum number of attempts.
        backoff_factor: Multiplier for exponential backoff delay (in seconds).
        expected_status_codes: A list of status codes that are considered
            successful. If None, any 2xx code is considered successful.
            Note: 429 is always treated as retryable, not a success.
        require_json: If True, the response must be valid JSON.
        required_json_keys: A list of keys that must be present in the
            response JSON. Implies `require_json=True`.
        # New 429 handling parameters
        handle_429: If True, specifically handle 429 Too Many Requests responses.
        default_429_wait_time: Default seconds to wait for a 429 if no Retry-After header.
        add_jitter: If True, add random jitter to wait times to prevent synchronized retries.
    """

    max_retries: int = 3
    backoff_factor: float = 1.5
    expected_status_codes: Optional[List[int]] = None
    require_json: bool = False
    required_json_keys: Optional[List[str]] = None
    handle_429: bool = True # Default to handling 429
    default_429_wait_time: float = 5.0 # Default wait 5 seconds if no Retry-After
    add_jitter: bool = True # Add jitter by default

    def __post_init__(self):
        """Prepare fields after initialization."""
        self.status_codes_set: Optional[Set[int]] = (
            set(self.expected_status_codes)
            if self.expected_status_codes
            else None
        )
        self.check_json: bool = self.require_json or bool(
            self.required_json_keys
        )
