#!/usr/bin/env python3
"""Score run.py output for the video transcript-and-summary benchmark.

  score.py REF_TXT OUT_DIR  -> writes OUT_DIR/results.json and prints a table

Transcript WER: reference and hypothesis are passed through the OpenAI Whisper
English text normalizer (lowercase, punctuation removed, numbers and contractions
standardised, "um"/"uh" dropped) before jiwer alignment, exactly as in the
speech-to-text list. Summary facts: a fixed checklist of facts stated in the
meeting (see FACTS) is matched against each summary with case-insensitive
substring/regex checks; the count is reported, not a quality judgement.

pip install jiwer whisper-normalizer
"""
import json
import os
import re
import sys

import jiwer
from whisper_normalizer.english import EnglishTextNormalizer

normalize = EnglishTextNormalizer()

# Facts stated in the first 10 minutes of AMI ES2002a, with the patterns accepted.
FACTS = {
    "purpose: kick-off for a new remote control": r"kick-?off.*remote control|remote control.*kick-?off",
    "brief: original, trendy, user-friendly": r"original.*trendy.*user[- ]friendly",
    "roles: project manager": r"project manager",
    "roles: industrial designer": r"industrial designer",
    "roles: marketing expert": r"marketing",
    "roles: user interface designer": r"user interface|ui designer",
    "process: three stages / three times": r"three[- ]stage|three stages|three times|3 stages",
    "icebreaker: draw favourite animal on whiteboard": r"favou?rite animal|whiteboard",
    "price: 25 euro selling price": r"25 euro|€25|twenty-five euro",
    "target: 50 million euro": r"50 million|fifty million|€50m",
    "cost cap: 12.50 euro (50% of price)": r"12\.50|12,50|twelve fifty|1250",
    "international sale affects design (zones / keypads)": r"international",
}


def facts_hit(summary):
    s = summary.lower()
    return {k: bool(re.search(p, s)) for k, p in FACTS.items()}


def main():
    ref_path, out_dir = sys.argv[1], sys.argv[2]
    with open(ref_path) as f:
        ref = normalize(f.read())

    results = {}
    for p in sorted(os.listdir(out_dir)):
        if not p.endswith(".json") or p == "results.json":
            continue
        with open(os.path.join(out_dir, p)) as f:
            r = json.load(f)
        hyp = normalize(r["transcript"])
        m = jiwer.process_words(ref, hyp)
        hits = facts_hit(r["summary"])
        results[p[:-5]] = {
            "version": r["version"],
            "run_at": r["run_at"],
            "wer": round(m.wer, 4),
            "substitutions": m.substitutions,
            "deletions": m.deletions,
            "insertions": m.insertions,
            "reference_words": len(ref.split()),
            "hypothesis_words": len(hyp.split()),
            "wall_seconds": r["wall_seconds"],
            "summary_words": len(r["summary"].split()),
            "summary_facts_hit": sum(hits.values()),
            "summary_facts_total": len(FACTS),
            "summary_facts": hits,
        }

    with open(os.path.join(out_dir, "results.json"), "w") as f:
        json.dump(results, f, indent=1)

    print(f"{'provider':12} {'WER':>6} {'total s':>8} {'facts':>6} {'sum words':>9}")
    for name, r in sorted(results.items(), key=lambda kv: kv[1]["wer"]):
        print(
            f"{name:12} {r['wer']*100:>5.1f}% {r['wall_seconds']['total']:>8} "
            f"{r['summary_facts_hit']:>3}/{r['summary_facts_total']:<2} {r['summary_words']:>9}"
        )


if __name__ == "__main__":
    main()
