#!/usr/bin/env python3
"""Render a transcription-safe editorial data sheet from regenerated results."""

from __future__ import annotations

import argparse
import json
from pathlib import Path


MODELS = ("qwen38", "qwen36", "gemma4")
NAMES = {"qwen38": "Qwen3.8", "qwen36": "Qwen3.6", "gemma4": "Gemma 4"}


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--summary", type=Path, required=True)
    parser.add_argument("--blind-writing", type=Path, required=True)
    parser.add_argument("--out", type=Path, required=True)
    args = parser.parse_args()
    summary = json.loads(args.summary.read_text())
    blind = json.loads(args.blind_writing.read_text())
    lines = ["# Article data sheet", "", f"Regenerated: {summary['generated_utc']}", ""]

    quality_order = (
        "instruction", "reasoning_runs", "reasoning_pass_at_3", "tools_single_runs",
        "tools_multi_runs", "coding_pass_at_1", "coding_pass_at_3", "coding_runs",
        "document_qa", "writing_mechanical", "multilingual_mechanical", "vision",
    )
    lines += ["## Quality", "", "| Measure | Qwen3.8 | Qwen3.6 | Gemma 4 |", "|---|---:|---:|---:|"]
    for measure in quality_order:
        cells = []
        for model in MODELS:
            row = summary["models"][model]["quality"].get(measure)
            cells.append("—" if not row else f"{row['successes']}/{row['total']} ({100*row['rate']:.1f}%; CI {100*row['low']:.1f}–{100*row['high']:.1f})")
        lines.append(f"| {measure.replace('_', ' ')} | " + " | ".join(cells) + " |")

    lines += ["", "## Synthetic speed", "", "| Condition | Qwen3.8 | Qwen3.6 | Gemma 4 |", "|---|---:|---:|---:|"]
    for condition in ("prompt_512", "prompt_8192", "prompt_32768", "decode_256"):
        cells = []
        for model in MODELS:
            row = summary["models"][model]["performance"]["synthetic"][condition]
            cells.append(f"{row['median_tokens_per_second']:.2f}")
        lines.append(f"| {condition} | " + " | ".join(cells) + " |")

    lines += ["", "## Context and memory", ""]
    for model in MODELS:
        lines.append(f"### {NAMES[model]}")
        lines.append("| Lane | Context | KV | Pass | Peak MiB | Headroom MiB | Input tokens |")
        lines.append("|---|---:|---|---|---:|---:|---:|")
        perf = summary["models"][model]["performance"]
        for lane, key in (("equal Q4", "equal_q4_f16_context"), ("best fit", "best_fit_context")):
            for row in perf[key]:
                lines.append(
                    f"| {lane} | {row['ctx_allocated']} | {row['cache_k']}/{row['cache_v']} | "
                    f"{'pass' if row['passed'] else 'FAIL'} | {row.get('peak_gpu_mib') or '—'} | {row.get('headroom_mib') or '—'} | {row.get('input_tokens') or '—'} |"
                )
        lines.append("")

    lines += ["## Streaming and power", "", "| Model | Load/ready s | Warm TTFT s | 64-token E2E s | Bench peak W |", "|---|---:|---:|---:|---:|"]
    for model in MODELS:
        perf = summary["models"][model]["performance"]
        stream = perf.get("stream_timing") or {}
        load = (stream.get("server") or {}).get("ready_seconds")
        power = (perf.get("synthetic_bench_telemetry") or {}).get("peak_power_watts")
        lines.append(f"| {NAMES[model]} | {load or 0:.3f} | {stream.get('median_ttft_seconds') or 0:.4f} | {stream.get('median_end_to_end_seconds') or 0:.4f} | {power or 0:.1f} |")

    lines += ["", "## Coding efficiency", "", "| Model | Successful runs | Median successful model s | Median calls | Invalid calls |", "|---|---:|---:|---:|---:|"]
    for model in MODELS:
        row = summary["models"][model]["coding_efficiency"]
        lines.append(f"| {NAMES[model]} | {row['successful_runs']}/{row['total_runs']} | {row['median_model_seconds_success'] or 0:.3f} | {row['median_tool_calls_success'] or 0:.1f} | {row['invalid_calls_total']} |")

    lines += ["", "## Reasoning efficiency", "", "| Model | No visible final | Length finishes | Median completion tokens | Median elapsed s |", "|---|---:|---:|---:|---:|"]
    for model in MODELS:
        row = summary["models"][model]["reasoning_efficiency"]
        lines.append(f"| {NAMES[model]} | {row['no_visible_final_runs']}/{row['runs']} | {row['length_finish_runs']} | {row['median_completion_tokens_all'] or 0:.1f} | {row['median_elapsed_seconds_all'] or 0:.3f} |")

    lines += ["", "## Blind writing", "", "| Model | Points | Percent |", "|---|---:|---:|"]
    for model in MODELS:
        row = blind["models"][model]
        lines.append(f"| {NAMES[model]} | {row['total_points']}/{row['possible_points']} | {row['percent_of_possible']:.1f}% |")

    lines += ["", "## Qwen3.8 versus Qwen3.6 paired outcomes", "", "| Category | Q3.8 only | Q3.6 only | Both pass | Both fail | p |", "|---|---:|---:|---:|---:|---:|"]
    for category, row in summary["paired"]["qwen38_vs_qwen36"].items():
        lines.append(f"| {category} | {row['left_only_pass']} | {row['right_only_pass']} | {row['both_pass']} | {row['both_fail']} | {row['mcnemar_exact_two_sided_p']:.4f} |")

    lines += ["", "## MTP retained summaries", "", "```json"]
    lines.append(json.dumps({model: summary["models"][model]["mtp"] for model in MODELS}, indent=2))
    lines += ["```", ""]
    args.out.write_text("\n".join(lines), encoding="utf-8")
    print(json.dumps({"out": str(args.out), "lines": len(lines)}))


if __name__ == "__main__":
    main()
