"""Capture per-page OCR text, bboxes, and latency from the vLLM OCR endpoint."""
from __future__ import annotations

import argparse
import base64
import json
import sys
from pathlib import Path
from typing import Any, Dict

import requests


def extract_capture(body: Dict[str, Any]) -> Dict[str, Any]:
    data = body.get("data") or {}
    if not isinstance(data, dict):
        data = {}
    blocks = ((data.get("ocr_text_json") or {}).get("blocks")) or []
    boxes = [list(b["bbox"]) for b in blocks if isinstance(b, dict) and b.get("bbox")]
    return {
        "text": data.get("text_lines", "") or "",
        "boxes": boxes,
        "elapsed_seconds": data.get("elapsed_seconds"),
    }


def write_capture(cap: Dict[str, Any], out_dir: Path, stem: str) -> None:
    out_dir.mkdir(parents=True, exist_ok=True)
    (out_dir / f"{stem}.txt").write_text(cap["text"], encoding="utf-8")
    (out_dir / f"{stem}.json").write_text(
        json.dumps({"boxes": cap["boxes"], "elapsed_seconds": cap["elapsed_seconds"]}),
        encoding="utf-8",
    )


def _payload(image_path: Path) -> Dict[str, Any]:
    suffix = image_path.suffix.lstrip(".").lower() or "png"
    return {
        "file": base64.b64encode(image_path.read_bytes()).decode("utf-8"),
        "type": "jpg" if suffix == "jpeg" else suffix,
        "skip_text_detection": False,
        "skip_table_detection": False,
        "recognize_math": False,
        "ocr_with_boxes": True,
    }


def capture_page(url: str, image_path: Path, out_dir: Path, timeout: float) -> Dict[str, Any]:
    resp = requests.post(url, json=_payload(image_path), timeout=timeout)
    cap = extract_capture(resp.json())
    if cap["elapsed_seconds"] is None:
        # Latency is a headline metric; a successful response with no timing means
        # the response contract changed. Surface it loudly instead of silently
        # dropping the page from the latency stats.
        print(
            f"WARNING: no elapsed_seconds in OCR response for {image_path.name}; "
            "latency for this page will be missing",
            file=sys.stderr,
        )
    write_capture(cap, out_dir, image_path.stem)
    return cap


def main() -> None:
    parser = argparse.ArgumentParser(description="Capture OCR text+boxes+latency per image.")
    parser.add_argument("images", nargs="+", type=Path)
    parser.add_argument("--url", required=True)
    parser.add_argument("--out-dir", type=Path, required=True)
    parser.add_argument("--timeout", type=float, default=900)
    args = parser.parse_args()
    for image in args.images:
        cap = capture_page(args.url, image, args.out_dir, args.timeout)
        print(f"captured {image.name}: {len(cap['boxes'])} boxes, {cap['elapsed_seconds']}s")


if __name__ == "__main__":
    main()
