"""Aria Circuit-Breaker (KAR-234).

pybreaker-wrappers fuer externe APIs. Verhindert Cascading-Failures
wenn Anthropic/OpenAI/Telegram-API down ist.

Usage:
    from aria_circuit import anthropic_cb, telegram_cb

    @anthropic_cb
    def call_claude(prompt):
        return requests.post("https://api.anthropic.com/v1/messages", ...)

    # Bei open circuit: pybreaker.CircuitBreakerError
"""
from __future__ import annotations
import pybreaker
import sys

# Defaults: 5 fails in 60s opens circuit, retry after 60s
DEFAULT_FAIL_MAX = 5
DEFAULT_RESET_TIMEOUT = 60


class AriaCircuitListener(pybreaker.CircuitBreakerListener):
    """Logging-listener for circuit state changes."""
    def __init__(self, name: str) -> None:
        self.name = name

    def state_change(self, cb, old_state, new_state) -> None:
        sys.stderr.write(f"[circuit] {self.name}: {old_state.name} -> {new_state.name}\n")
        sys.stderr.flush()

    def failure(self, cb, exc) -> None:
        sys.stderr.write(f"[circuit] {self.name}: failure ({type(exc).__name__}: {exc})\n")
        sys.stderr.flush()


def make_cb(name: str, fail_max: int = DEFAULT_FAIL_MAX, reset_timeout: int = DEFAULT_RESET_TIMEOUT) -> pybreaker.CircuitBreaker:
    return pybreaker.CircuitBreaker(
        fail_max=fail_max,
        reset_timeout=reset_timeout,
        name=name,
        listeners=[AriaCircuitListener(name)],
    )


# Pre-defined breakers for common APIs
anthropic_cb = make_cb("anthropic_api", fail_max=5, reset_timeout=60)
openai_cb = make_cb("openai_api", fail_max=5, reset_timeout=60)
telegram_cb = make_cb("telegram_api", fail_max=10, reset_timeout=30)  # Telegram is fragile, more tolerant
linear_cb = make_cb("linear_api", fail_max=5, reset_timeout=60)
github_cb = make_cb("github_api", fail_max=5, reset_timeout=60)
supabase_cb = make_cb("supabase_api", fail_max=5, reset_timeout=60)
