"""
Solution: the test gate from Lab 05 (evals/gate.py and run_evals.py).
"""

TOLERANCES = {
    "hit_at_1": 0.0,
    "recall_at_k": 0.0,
    "mrr_at_k": 0.0,
    "citation_validity": 0.10,
    "faithfulness": 0.10,
    "refusal_accuracy": 0.10,
}
EPSILON = 1e-9


def compare(current: dict[str, float], baseline: dict[str, float],
            tolerances: dict[str, float] = TOLERANCES) -> dict[str, str]:
    out = {}
    for metric, value in current.items():
        base = baseline[metric]
        tolerance = tolerances.get(metric, 0.0)
        if value < base - tolerance - EPSILON:
            out[metric] = "regressed"
        elif value > base + EPSILON:
            out[metric] = "improved"
        else:
            out[metric] = "ok"
    return out


def critical_failures(cases: list[dict]) -> list[str]:
    return [c["id"] for c in cases if c["critical"] and any(v < 1 for v in c["checks"].values())]


def gate_passed(statuses: dict[str, str], critical: list[str]) -> bool:
    return not critical and all(s != "regressed" for s in statuses.values())


def wobble(scores: list[float]) -> float:
    return max(scores) - min(scores)


def cries_wolf(scores: list[float], tolerance: float) -> bool:
    # The worst pair: the highest run saved as the baseline, the lowest as the new run.
    return min(scores) < max(scores) - tolerance - EPSILON
