"""
Practice: the test gate from Lab 05 (evals/gate.py and run_evals.py), on the help center from the video.

Fill in the TODOs, then run the tests:
    pytest test_gate_practice.py        (locally)
or press "Run tests" on the chapter page.
"""

# Allowed drop below the baseline before the gate fails (the lab's values).
# Search gives the same results every run, so any drop is real; answer and judge scores wobble.
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  # float noise


def compare(current: dict[str, float], baseline: dict[str, float],
            tolerances: dict[str, float] = TOLERANCES) -> dict[str, str]:
    """Compare each score in `current` with the same score in `baseline`. Return {metric: status}:
      - "regressed" if current < baseline - tolerance - EPSILON   (a missing tolerance means 0)
      - "improved"  if current > baseline + EPSILON
      - "ok"        otherwise

    TODO 1
    """
    return {metric: "ok" for metric in current}


def critical_failures(cases: list[dict]) -> list[str]:
    """Each case is {"id": ..., "critical": bool, "checks": {check: 0.0 or 1.0}}.
    Return the ids of critical cases where any check failed (scored below 1), in order.

    TODO 2
    """
    return []


def gate_passed(statuses: dict[str, str], critical: list[str]) -> bool:
    """The gate passes only if no score regressed AND no critical question failed.

    TODO 3
    """
    return True


def wobble(scores: list[float]) -> float:
    """How far one score moved across runs of unchanged code: the highest minus the lowest.

    TODO 4
    """
    return 0.0


def cries_wolf(scores: list[float], tolerance: float) -> bool:
    """Could the gate block unchanged code? True if some pair of these unchanged runs, one saved as
    the baseline and the other as the new run, would count as "regressed" under this tolerance.

    TODO 5
    """
    return False
