"""Error classifier and TTL-based key blocking."""

from __future__ import annotations

from llm_rotator._types import Candidate
from llm_rotator.backends import AbstractStateBackend
from llm_rotator.exceptions import (
    KeyDeadError,
    LLMRotatorError,
    ModelRateLimitError,
    ServerError,
)


class CircuitBreaker:
    """Classifies errors and manages key/model blocks via a state backend."""

    def __init__(
        self,
        backend: AbstractStateBackend,
        default_block_ttl: int = 60,
    ) -> None:
        self._backend = backend
        self._default_block_ttl = default_block_ttl

    async def record_failure(self, candidate: Candidate, error: LLMRotatorError) -> None:
        """Classify error and update backend blocks accordingly."""
        if isinstance(error, KeyDeadError):
            await self._backend.mark_key_dead(candidate.key_alias)
        elif isinstance(error, ModelRateLimitError):
            ttl = error.retry_after if error.retry_after is not None else self._default_block_ttl
            await self._backend.block_key_for_model(candidate.key_alias, candidate.model, ttl)
        elif isinstance(error, ServerError):
            await self._backend.block_key_for_model(
                candidate.key_alias, candidate.model, self._default_block_ttl
            )

    async def is_candidate_available(self, candidate: Candidate) -> bool:
        """Check if a candidate is available (not blocked)."""
        return await self._backend.is_key_available(candidate.key_alias, candidate.model)
