#!/usr/bin/env python3
"""build.py — inline the brand font into the review page.

The Artifact CSP blocks every external host, font CDNs included, so Montserrat has to
travel inside the file as a data URI or the page silently falls back to a system face
and stops being brand-locked (`CLAUDE.md` §8). The variable TTF is 745KB -> ~1.0MB of
base64, comfortably under the 16MB artifact cap.

⛔ EDIT `review.template.html`, NEVER `reel-review.html` — the built file is generated and
your edit is lost on the next run. Then republish the built file to the EXISTING artifact
url (R24_PROJECT.md §0 rule 6); publishing without it orphans the operator's bookmark.

Usage: python3 qa/review/build.py
"""
import base64
import sys
from pathlib import Path

HERE = Path(__file__).resolve().parent
ROOT = HERE.parents[1]
FONT = ROOT / "brand" / "fonts" / "Montserrat[wght].ttf"
TPL = HERE / "review.template.html"
OUT = HERE / "reel-review.html"
PREVIEW = HERE / "preview"
CAP_MB = 16.0

# ⛔ THE REEL TRAVELS INSIDE THE PAGE. A review page that asks the reviewer to go and
# find the file is a page that does not get used — which is the whole failure ADD-35
# exists to end. The master is 78MB against a 16MB cap, so what ships is a
# NATIVE-RESOLUTION compressed copy, made by:
#
#   ffmpeg -i output/<reel>.r24.mp4 -c:v libx264 -preset slow -crf 30 \
#          -pix_fmt yuv420p -movflags +faststart -c:a aac -b:a 96k \
#          qa/review/preview/<reel>.r24.review.mp4
#
# 1080x1920 at CRF 30 is 4.5MB -> ~6.0MB of base64. NO DOWNSCALE: the resolution is
# what makes a pin about a stroke or a label trustworthy, and dropping to 720 to save
# 1.7MB we did not need would have quietly changed what the operator is judging.


def newest_preview():
    """The most recently written review copy in preview/. Newest wins on purpose: the
    page is republished right after a render, and that render's copy is the one meant."""
    mp4s = sorted(PREVIEW.glob("*.mp4"), key=lambda f: f.stat().st_mtime, reverse=True)
    if not mp4s:
        raise SystemExit(f"FAIL: no .mp4 in {PREVIEW} — encode a review copy first "
                         f"(see this file's header) or the page ships with no reel in it")
    return mp4s[0]


if not FONT.exists():
    raise SystemExit(f"FAIL: no brand font at {FONT} — the page would fall back to a "
                     f"system face and stop being brand-locked")
tpl = TPL.read_text()
for token in ("__FONT__", "__VIDEO__", "__VIDEONAME__"):
    if token not in tpl:
        raise SystemExit(f"FAIL: {TPL.name} has no {token} placeholder — refusing to write "
                         f"a page that is missing its face or its reel")

mp4 = newest_preview()
# The name the operator sees and the localStorage key are the MASTER's name, not the
# review copy's: notes must survive swapping the full-quality master in over it.
shown = mp4.name.replace(".review.mp4", ".mp4")
out = (tpl.replace("__FONT__", base64.b64encode(FONT.read_bytes()).decode())
          .replace("__VIDEO__", "data:video/mp4;base64," + base64.b64encode(mp4.read_bytes()).decode())
          .replace("__VIDEONAME__", shown))
OUT.write_text(out)
mb = OUT.stat().st_size / 1e6
print(f"wrote {OUT.relative_to(ROOT)} — {mb:.2f} MB   (reel: {mp4.name}, "
      f"{mp4.stat().st_size / 1e6:.2f} MB)")
if mb > CAP_MB:
    raise SystemExit(f"⛔ FAIL: {mb:.2f} MB is over the {CAP_MB:.0f} MB artifact cap — "
                     f"re-encode the review copy at a higher CRF, never at a lower "
                     f"resolution (see this file's header)")
sys.exit(0)
