#!/usr/bin/env python3
"""Extract simulator-visible graph/KV metadata from Qwen235 server starts."""

from __future__ import annotations

import argparse
import json
import re
from pathlib import Path


CONFIGS = ("tp4_ep1_mns64", "tp4_ep1_mns128", "tp8_ep8_mns64", "tp8_ep8_mns128")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--case-root", type=Path, required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    configs = {}
    for config in CONFIGS:
        log = args.case_root / "real" / config / "trial1" / "logs" / "server.log"
        text = log.read_text(errors="replace")
        token_matches = re.findall(r"GPU KV cache size:\s*([0-9,]+) tokens", text)
        capture_matches = re.findall(r"cudagraph_capture_sizes': \[([^]]+)\]", text)
        if not token_matches or not capture_matches:
            raise ValueError(f"missing runtime metadata in {log}")
        tokens = int(token_matches[-1].replace(",", ""))
        if tokens % 16:
            raise ValueError(f"KV token count is not block aligned: {tokens}")
        capture = [int(value.strip()) for value in capture_matches[-1].split(",")]
        configs[config] = {
            "num_gpu_blocks": tokens // 16,
            "capture_sizes": capture,
            "source_log": str(log.resolve()),
        }
    payload = {"schema": "qwen235-v020-runtime-contract-v1", "configs": configs}
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
    print(json.dumps(payload, sort_keys=True))


if __name__ == "__main__":
    main()
