r"""
Rebuild the demo broadcast audio in ONE step so it can never go stale: re-score real.json, render the
commentary clips, and VERIFY every line has a clip. Run this after ANY commentary change — the missing
clips it guards against are exactly what makes the live page fall back to a browser voice (the
"too many voices" trap; the recorded MP4 simply goes silent on the uncovered line).

  ..\..\..\.venv-demo\Scripts\python.exe demo/record/rebuild_demo.py

All languages render through Google Cloud neural TTS (live/tts/synth.py — needs auth), one consistent
male + one female voice each. Add a language by listing it in LANGS below (and giving it a BCP-47 code
in synth.py's LANG_CODE).
"""
import json
import subprocess
import sys
from pathlib import Path

HERE = Path(__file__).resolve().parent
ROOT = HERE.parent.parent                                   # v3/broadcast
REAL = ROOT / "demo" / "data" / "races" / "real.json"
INDEX = ROOT / "demo" / "data" / "audio" / "index.json"
TTS = ROOT / "live" / "tts"

LANGS = ["en", "sv"]                                        # all rendered by live/tts/synth.py


def rescore():
    """Re-run the engine over real.json (idempotent) so the clips match the current commentary."""
    sys.path.insert(0, str(ROOT.parent / "scoring"))
    from score_race import enrich
    out = enrich(json.loads(REAL.read_text(encoding="utf-8")))
    REAL.write_text(json.dumps(out, ensure_ascii=False, separators=(",", ":")), encoding="utf-8")
    print(f"re-scored {REAL.name}: {len(out['events'])} events", flush=True)


def synth(langs):
    if langs:
        subprocess.run([sys.executable, str(TTS / "synth.py"), "--lang", ",".join(langs)], check=True)


def verify():
    """Fail loudly if any feed line lacks a clip — that's the line that would use a fallback voice."""
    real = json.loads(REAL.read_text(encoding="utf-8"))
    idx = json.loads(INDEX.read_text(encoding="utf-8"))
    ok = True
    for lang in LANGS:
        lines = {(e.get("i18n") or {}).get(lang, "").strip() for e in real["events"]}
        lines.discard("")
        miss = [t for t in lines if t not in idx.get(lang, {})]
        ok = ok and not miss
        flag = "OK" if not miss else f"!! {len(miss)} MISSING -> would use a fallback voice"
        print(f"  {lang}: {len(lines)} lines, {len(lines) - len(miss)} with clips  {flag}")
    if not ok:
        raise SystemExit("coverage incomplete — re-run after fixing the synth, see MISSING above")
    print("coverage OK — every line has a clip: one male + one female voice per language.")


def main():
    rescore()
    synth(LANGS)
    verify()


if __name__ == "__main__":
    main()
