"""Degradation level tracking and call-site filtering."""

from __future__ import annotations

from typing import TYPE_CHECKING

from genesis.routing.types import DegradationLevel

if TYPE_CHECKING:
    from genesis.resilience.state import ResilienceStateMachine

# L2 (Reduced) skips these call sites
_L2_SKIP = {"12_surplus_brainstorm", "13_morning_report", "judge"}

# L3 (Essential) only keeps these call sites.
# Note: "2_triage" removed from this set 2026-05-10 alongside its removal from
# config/model_routing.yaml (the awareness loop's classify_depth replaced it).
_L3_KEEP = {"3_micro_reflection", "21_embeddings", "22_tagging"}

# Tmp pressure skip lists — separate from cloud degradation because disk
# pressure requires different shedding than provider outages.
# MODERATE (yellow): suppress surplus + morning report (same as cloud L2)
_TMP_MODERATE_SKIP = {"12_surplus_brainstorm", "13_morning_report"}
# HIGH (orange): also suppress background reflections, ego, calibration, sweeps
_TMP_HIGH_SKIP = _TMP_MODERATE_SKIP | {
    "5_deep_reflection", "6_strategic_reflection", "7_ego_cycle",
    "14_weekly_self_assessment", "16_quality_calibration",
    "28_observation_sweep", "judge",
}


def should_skip_call_site(call_site_id: str, level: DegradationLevel) -> bool:
    """Return True if call_site_id should be skipped at the given degradation level."""
    if level in (DegradationLevel.NORMAL, DegradationLevel.FALLBACK):
        return False
    if level == DegradationLevel.REDUCED:
        return call_site_id in _L2_SKIP
    if level == DegradationLevel.ESSENTIAL:
        return call_site_id not in _L3_KEEP
    # L4/L5 — handled by circuit breaker, not call-site filtering
    return False


class DegradationTracker:
    def __init__(self, *, resilience_state: ResilienceStateMachine | None = None):
        self._level = DegradationLevel.NORMAL
        self._resilience_state = resilience_state

    @property
    def current_level(self) -> DegradationLevel:
        return self._level

    def update(self, level: DegradationLevel) -> None:
        self._level = level

    def update_from_resilience(self) -> None:
        """Update degradation level from composite resilience state."""
        if self._resilience_state is None:
            return
        self._level = self._resilience_state.current.to_legacy_degradation_level()

    def should_skip(self, call_site_id: str) -> bool:
        # Check cloud/provider-based degradation first
        if should_skip_call_site(call_site_id, self._level):
            return True
        # Check tmp_pressure axis independently
        if self._resilience_state is not None:
            from genesis.resilience.state import TmpPressureStatus
            tmp = self._resilience_state.current.tmp_pressure
            if tmp == TmpPressureStatus.CRITICAL:
                return call_site_id not in _L3_KEEP
            if tmp == TmpPressureStatus.HIGH:
                return call_site_id in _TMP_HIGH_SKIP
            if tmp == TmpPressureStatus.MODERATE:
                return call_site_id in _TMP_MODERATE_SKIP
        return False
