#!/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]
TTS = PROJECT / "log/tts-verification.json"
PRONUNCIATION = PROJECT / "log/tts-pronunciation.json"
LAYOUT = PROJECT / "image/layout-manifest.json"
AUDIO = PROJECT / "audio/story-full.wav"
LAYOUT_IMAGE = PROJECT / "image/layout-1920x1080.png"
OUTPUT = PROJECT / "output/footage/footage.mp4"
SUBMISSION = PROJECT / "log/footage-submission.json"
BASE = "http://192.168.1.104:8022"


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 duration(path):
    result = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=nw=1:nk=1", str(path)], capture_output=True, text=True, check=True)
    return float(result.stdout.strip())


def get_job(job_id):
    with urllib.request.urlopen(
        BASE + "/v1/footage-render-huyenan/jobs/" + job_id, timeout=30
    ) as response:
        return json.load(response)


def main():
    if not TTS.exists() or not PRONUNCIATION.exists() or not LAYOUT.exists() or not AUDIO.exists() or not LAYOUT_IMAGE.exists():
        print("Footage blocked: verified TTS/layout inputs are missing", file=sys.stderr)
        return 1
    tts = json.loads(TTS.read_text(encoding="utf-8"))
    pronunciation = json.loads(PRONUNCIATION.read_text(encoding="utf-8"))
    layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
    canon = tts.get("source_canon_sha256")
    if (
        tts.get("verified") is not True
        or tts.get("pronunciation_verified") is not True
        or pronunciation.get("verified") is not True
        or pronunciation.get("semantic_content_changed") is not False
        or tts.get("source_sha256") != pronunciation.get("output_sha256")
        or tts.get("spoken_narration_sha256") != pronunciation.get("source_sha256")
        or tts.get("pronunciation_receipt_sha256") != sha(PRONUNCIATION)
        or tts.get("output_sha256") != sha(AUDIO)
        or layout.get("verified") is not True
        or layout.get("visual_qa", {}).get("verified") is not True
        or layout.get("source_canon_sha256") != canon
    ):
        print("Footage blocked: TTS/layout canon hash mismatch", file=sys.stderr)
        return 1
    layout_hash = sha(LAYOUT_IMAGE)
    audio_hash = sha(AUDIO)
    if SUBMISSION.exists():
        prior = json.loads(SUBMISSION.read_text(encoding="utf-8"))
        if (
            prior.get("source_canon_sha256") != canon
            or prior.get("layout_sha256") != layout_hash
            or prior.get("audio_sha256") != audio_hash
            or not prior.get("job_id")
        ):
            print("Footage blocked: prior submission belongs to different authority/input bytes", file=sys.stderr)
            return 1
        job = get_job(prior["job_id"])
        status = job.get("status")
        if status in {"queued", "running", "completed"}:
            print(json.dumps({"job_id": prior["job_id"], "status": status, "resumed": True, "source_canon_sha256": canon}, ensure_ascii=False))
            return 0
        print(f"Footage blocked: prior job ended {status}; inspect before a deliberate replacement", file=sys.stderr)
        return 1
    if OUTPUT.exists():
        print("Footage blocked: unreceipted output already exists; do not overwrite", 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("Footage blocked: GPU endpoint is not healthy", file=sys.stderr)
        return 1

    payload = {
        "layout": str(LAYOUT_IMAGE),
        "footage_dir": "/data/video-pipeline/GacMaiAudio/footage",
        "pattern": "*.mp4", "recursive": True,
        "audio": str(AUDIO), "output": str(OUTPUT),
        "seed": 11011, "overwrite": False,
        "width": 1920, "height": 1080, "fps": 30,
        "center_x": 656, "center_y": 0, "center_width": 608, "center_height": 1080,
        "video_encoder": "h264_nvenc", "preset": "p4", "cq": 21,
    }
    request = urllib.request.Request(
        BASE + "/v1/footage-render-huyenan/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("Footage 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,
        "output": str(OUTPUT.relative_to(PROJECT)), "payload": payload,
        "layout_sha256": layout_hash, "audio_sha256": audio_hash,
        "pronunciation_sha256": pronunciation.get("output_sha256"),
        "pronunciation_receipt_sha256": sha(PRONUNCIATION),
        "expected_duration_seconds": duration(AUDIO),
        "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, "submission": str(SUBMISSION)}, ensure_ascii=False))
    return 0


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