#!/usr/bin/env python3
import hashlib
import json
import subprocess
import sys
import urllib.request
from datetime import datetime, timezone
from pathlib import Path

PROJECT = Path(__file__).resolve().parents[1]
PROMOTION = PROJECT / "story/promotion-report.json"
INTRO_RECEIPT = PROJECT / "log/intro-render.json"
FOOTAGE_RECEIPT = PROJECT / "log/footage-job.json"
INTRO = PROJECT / "output/intro/intro.mp4"
FOOTAGE = PROJECT / "output/footage/footage.mp4"
OUTPUT = PROJECT / "output/final.mp4"
SUBMISSION = PROJECT / "log/final-submission.json"
BASE = "http://192.168.1.104:8023"


def sha(path):
    digest = hashlib.sha256()
    with path.open("rb") as handle:
        for block in iter(lambda: handle.read(8 * 1024 * 1024), b""):
            digest.update(block)
    return digest.hexdigest()


def probe(path):
    result = subprocess.run([
        "ffprobe", "-v", "error", "-show_entries", "format=duration,size",
        "-show_entries", "stream=index,codec_name,width,height,sample_rate,channels",
        "-of", "json", str(path),
    ], capture_output=True, text=True, check=True)
    return json.loads(result.stdout)


def main():
    required = [PROMOTION, INTRO_RECEIPT, FOOTAGE_RECEIPT, INTRO, FOOTAGE]
    if any(not path.exists() for path in required):
        print("Final blocked: verified intro/footage inputs are missing", file=sys.stderr)
        return 1
    promotion = json.loads(PROMOTION.read_text(encoding="utf-8"))
    intro_receipt = json.loads(INTRO_RECEIPT.read_text(encoding="utf-8"))
    footage_receipt = json.loads(FOOTAGE_RECEIPT.read_text(encoding="utf-8"))
    canon = promotion.get("spoken_sha256")
    if (
        promotion.get("verified") is not True
        or intro_receipt.get("verified") is not True
        or footage_receipt.get("verified") is not True
        or intro_receipt.get("source_canon_sha256") != canon
        or footage_receipt.get("source_canon_sha256") != canon
        or intro_receipt.get("visual_qa", {}).get("verified") is not True
        or footage_receipt.get("visual_qa", {}).get("verified") is not True
        or intro_receipt.get("output_sha256") != sha(INTRO)
        or footage_receipt.get("output_sha256") != sha(FOOTAGE)
    ):
        print("Final blocked: authority receipt mismatch", file=sys.stderr)
        return 1
    if OUTPUT.exists():
        print("Final blocked: final already exists; inspect existing job instead of overwriting", file=sys.stderr)
        return 1
    intro_probe = probe(INTRO)
    footage_probe = probe(FOOTAGE)
    if not any(s.get("codec_name") == "aac" for s in footage_probe.get("streams", [])):
        print("Final blocked: footage does not carry narration audio", file=sys.stderr)
        return 1

    with urllib.request.urlopen(BASE + "/health", timeout=20) as response:
        health = json.load(response)
    if health.get("status") != "ok" or health.get("h264_nvenc") is not True:
        print("Final blocked: final GPU endpoint is not healthy", file=sys.stderr)
        return 1

    payload = {
        "intro_video_path": str(INTRO),
        "footage_video_path": str(FOOTAGE),
        "output_video_path": str(OUTPUT),
        "fps": 30,
        "width": 1920,
        "height": 1080,
    }
    request = urllib.request.Request(
        BASE + "/v1/huyenan-render-final/jobs",
        data=json.dumps(payload).encode(), headers={"Content-Type": "application/json"}, method="POST",
    )
    with urllib.request.urlopen(request, timeout=30) as response:
        job = json.load(response)
    job_id = job.get("job_id")
    if not job_id or job.get("status") not in {"queued", "running"}:
        print("Final submission did not return a valid job", file=sys.stderr)
        return 1
    receipt = {
        "version": 1, "verified": False, "source_canon_sha256": canon,
        "job_id": job_id, "status": job.get("status"), "endpoint": BASE,
        "intro_duration_seconds": float(intro_probe["format"]["duration"]),
        "footage_duration_seconds": float(footage_probe["format"]["duration"]),
        "expected_duration_seconds": float(intro_probe["format"]["duration"]) + float(footage_probe["format"]["duration"]),
        "intro_sha256": sha(INTRO), "footage_sha256": sha(FOOTAGE),
        "output": str(OUTPUT.relative_to(PROJECT)), "payload": payload,
        "submitted_at": datetime.now(timezone.utc).isoformat(),
    }
    SUBMISSION.parent.mkdir(parents=True, exist_ok=True)
    SUBMISSION.write_text(json.dumps(receipt, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"job_id": job_id, "status": job.get("status"), "source_canon_sha256": canon}, ensure_ascii=False))
    return 0


if __name__ == "__main__":
    sys.exit(main())
