#!/usr/bin/env python3
from __future__ import annotations

import argparse
import hashlib
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path("/data/video-pipeline/HaTramAudio/project/013-Ngay-Buu-Cuc-Cu-Sang-Den")
PROJECT_ID = "013-Ngay-Buu-Cuc-Cu-Sang-Den"
RUN_ID = "run-20260720T110344Z-f6c08be9"
OWNER = "zoro"


def now() -> str:
    return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")


def sha(path: Path) -> str:
    h = hashlib.sha256()
    with path.open("rb") as f:
        for block in iter(lambda: f.read(8 * 1024 * 1024), b""):
            h.update(block)
    return h.hexdigest()


def guard() -> None:
    lock = json.loads((ROOT / ".ownership-lock.json").read_text(encoding="utf-8"))
    for key, value in {"project_id": PROJECT_ID, "run_id": RUN_ID, "owner": OWNER, "status": "active"}.items():
        if lock.get(key) != value:
            raise RuntimeError(f"ownership mismatch: {key}")


def probe(path: Path) -> dict:
    return json.loads(subprocess.check_output([
        "ffprobe", "-v", "error", "-show_entries",
        "format=duration,size:stream=index,codec_type,codec_name,width,height,sample_rate,channels",
        "-of", "json", str(path),
    ]))


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("stage", choices=["footage", "final", "upload"])
    args = parser.parse_args()
    guard()
    sources = {
        "footage": ROOT / "output" / "footage" / "footage.mp4",
        "final": ROOT / "output" / "final.mp4",
        "upload": ROOT / "output" / "final-upload.mp4",
    }
    source = sources[args.stage]
    data = probe(source)
    duration = float(data["format"]["duration"])
    outdir = ROOT / "log" / f"{args.stage}-check"
    outdir.mkdir(parents=True, exist_ok=True)
    points = [("10", duration * 0.1), ("50", duration * 0.5), ("90", duration * 0.9)]
    if args.stage in {"final", "upload"}:
        points = [("intro", min(5.0, duration * 0.001)), ("transition", min(12.0, duration * 0.01))] + points
    frames = []
    for label, timestamp in points:
        path = outdir / f"frame-{label}.png"
        subprocess.check_call([
            "ffmpeg", "-hide_banner", "-loglevel", "error", "-y", "-ss", f"{timestamp:.6f}",
            "-i", str(source), "-frames:v", "1", str(path),
        ])
        image_probe = probe(path)
        stream = image_probe["streams"][0]
        frames.append({
            "label": label,
            "timestamp_seconds": timestamp,
            "path": str(path),
            "sha256": sha(path),
            "bytes": path.stat().st_size,
            "width": stream.get("width"),
            "height": stream.get("height"),
        })
    manifest = {
        "schema_version": 1,
        "project_id": PROJECT_ID,
        "run_id": RUN_ID,
        "stage": args.stage,
        "status": "extracted",
        "verified": False,
        "source_path": str(source),
        "source_sha256": sha(source),
        "source_duration_seconds": duration,
        "source_probe": data,
        "frames": frames,
        "created_at": now(),
    }
    path = outdir / "frame-manifest.json"
    guard()
    path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"status": "extracted", "verified": False, "manifest": str(path), "source_sha256": manifest["source_sha256"]}, ensure_ascii=False))


if __name__ == "__main__":
    main()
