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

PROJECT = Path(__file__).resolve().parents[1]
MANIFEST = PROJECT / "script" / "project-manifest.json"
PLAN = PROJECT / "script" / "production-plan-v3.json"
REPORT = PROJECT / "log" / "v3" / "production-verification.json"


def read_json(path):
    if not path.exists():
        return None
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return None


def probe(path):
    result = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration,size,format_name", "-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 receipt_hash_ok(path, canon_hash):
    data = read_json(path)
    return bool(data and data.get("verified") is True and data.get("source_canon_sha256") == canon_hash), data


def main():
    issues = []
    manifest = read_json(MANIFEST)
    plan = read_json(PLAN)
    if not manifest or not plan:
        raise SystemExit("Missing project manifest or production plan")
    canon_hash = manifest.get("canon_hash")
    if not canon_hash or manifest.get("canon_version") != 3:
        issues.append("canon_v3_not_promoted")
    if plan.get("canon_sha256") != canon_hash:
        issues.append("production_plan_canon_hash_mismatch")
    if plan.get("reuse_v2") is not False:
        issues.append("reuse_v2_not_forbidden")

    receipt_specs = {
        "story": PROJECT / "story" / "v3" / "promotion-report.json",
        "tts": PROJECT / "log" / "v3" / "tts-verification.json",
        "images": PROJECT / "image" / "v3" / "layout-manifest.json",
        "footage": PROJECT / "log" / "v3" / "footage-job.json",
        "intro": PROJECT / "log" / "v3" / "intro-render.json",
        "final": PROJECT / "log" / "v3" / "final-render.json",
        "metadata": PROJECT / "log" / "v3" / "metadata-verification.json",
    }
    receipts = {}
    for name, path in receipt_specs.items():
        data = read_json(path)
        receipts[name] = {"path": str(path.relative_to(PROJECT)), "present": data is not None}
        if data is None:
            issues.append(f"missing_or_invalid_receipt:{name}")
            continue
        verified = data.get("verified") is True
        source_hash = data.get("source_canon_sha256") or data.get("spoken_sha256")
        receipts[name].update({"verified": verified, "source_canon_sha256": source_hash})
        if not verified:
            issues.append(f"receipt_not_verified:{name}")
        if source_hash != canon_hash:
            issues.append(f"receipt_canon_hash_mismatch:{name}")

    final_path = PROJECT / "output" / "v3" / "final.mp4"
    final_probe = None
    if not final_path.exists() or final_path.stat().st_size <= 0:
        issues.append("missing_final_v3")
    else:
        try:
            final_probe = probe(final_path)
            streams = final_probe.get("streams", [])
            video = [item for item in streams if item.get("width")]
            audio = [item for item in streams if item.get("sample_rate")]
            if len(video) != 1 or len(audio) != 1:
                issues.append("final_stream_count_invalid")
            else:
                if video[0].get("width") != 1920 or video[0].get("height") != 1080:
                    issues.append("final_resolution_invalid")
                if video[0].get("codec_name") != "h264":
                    issues.append("final_video_codec_invalid")
                if audio[0].get("codec_name") != "aac":
                    issues.append("final_audio_codec_invalid")
        except Exception as exc:
            issues.append(f"final_probe_failed:{exc}")

    metadata_path = PROJECT / "output" / "v3" / "info.txt"
    if not metadata_path.exists() or len(metadata_path.read_text(encoding="utf-8").strip()) < 100:
        issues.append("metadata_v3_missing_or_too_short")

    publish_block = PROJECT / "DO_NOT_PUBLISH_V2.json"
    if not publish_block.exists():
        issues.append("v2_publish_block_missing")

    report = {
        "version": 3,
        "verified": not issues,
        "status": "passed" if not issues else "failed",
        "source_canon_sha256": canon_hash,
        "reuse_v2": False,
        "receipts": receipts,
        "final": {
            "path": str(final_path.relative_to(PROJECT)),
            "present": final_path.exists(),
            "probe": final_probe,
        },
        "issues": issues,
        "checked_at": datetime.now(timezone.utc).isoformat(),
    }
    REPORT.parent.mkdir(parents=True, exist_ok=True)
    REPORT.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"verified": report["verified"], "issues": issues, "report": str(REPORT)}, ensure_ascii=False))
    return 0 if report["verified"] else 1


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