"""Solution for the Lab 08 practice: canaries and production monitoring."""
import math


def request_signals(text: str, declared_seconds: float, decoded_seconds: float) -> dict:
    n = len(text.split())
    declared = max(declared_seconds, 0.1)
    return {"empty": n == 0, "words_per_second": n / declared,
            "duration_mismatch": abs(decoded_seconds / declared - 1) > 0.05}


def window_z(value: float, n: int, mean: float, sd: float) -> float:
    if n <= 0:
        return 0.0
    return (value - mean) / (sd / math.sqrt(n))


def cusum(zs: list[float], h: float, k: float = 0.5, cooldown: int = 12) -> list[int]:
    alarms, s, quiet_until = [], 0.0, -1
    for t, z in enumerate(zs):
        s = max(0.0, s + z - k)
        if t <= quiet_until:
            continue
        if s > h:
            alarms.append(t)
            quiet_until = t + cooldown
            s = 0.0
    return alarms


def canary_alerts(rnd: dict, golden: dict, previous: dict | None = None, wer_margin: float = 2.0) -> list[str]:
    out = []
    if rnd["changed"]:
        out.append("transcripts changed")
    if rnd["errors"]:
        out.append("requests failed")
    if rnd["must_pass_failures"]:
        out.append("must-pass")
    limit = golden["wer"] + wer_margin
    if rnd["wer"] > limit and (previous is None or previous["wer"] > limit):
        out.append("wer")
    return out
