"""Generate cheap placeholder media for the full 5-scale RING (scales design §3).

SUPERSEDED (session 0016): the ring now uses real strict-PD footage in a ROTATING
POOL per scale, regenerated by `simulator/build_pool_manifest.py` (which also makes
the new coast-edge transition placeholders). This generator built the older
one-base-per-scale forest ring (cosmos/orbit/forest/reef/abyss) and is kept only
for reference / a clean-room placeholder rebuild; it does NOT match the current
pool manifest or ring order (cosmos → orbit → coast → reef → abyss).


Produces offline synthetic placeholders for all five ring scales — **cosmos**
(NASA/Hubble), **orbit** (NASA/ISS), **forest** (NPS/USGS), **reef** (NOAA Ocean
Exploration), and **abyss** (NOAA Ocean Exploration) — plus the short zoom/warp
**transition** clips between adjacent scales. Forest reuses the real POC base from
`setup_sample_media.py` (or a synthetic placeholder if absent); all others are
generated as labelled solid-tint clips.

This is deliberately the CHEAP path: the manifest records the real true-PD
provenance (NASA / NPS / USGS / NOAA, 17 U.S.C. §105), but the bytes here are
labelled synthetic placeholders for look-tuning the ring navigation. The Right dream
is real-time (Kuwahara WebGL shader), so no per-clip ML bake is needed; each scale
carries a raw base only. Real strict-PD bases replace these placeholders via the
content pipeline (see `docs/content-sourcing.md`).

Usage:  python simulator/setup_scales_media.py
Requires: ffmpeg on PATH (or `pip install imageio-ffmpeg`).
"""

from __future__ import annotations

import shutil
import subprocess
from pathlib import Path

MEDIA = Path(__file__).parent / "sample_media"
DUR = 6           # base clip seconds
XDUR = 1.5        # transition seconds
SIZE = "1280x720"
FPS = 25

# Each scale: (dir, base color, on-screen placeholder label).
SCALES = {
    "cosmos": ("0x05060f", "COSMOS — NASA/Hubble (PD placeholder)"),
    "orbit": ("0x081427", "ORBIT — NASA/ISS (PD placeholder)"),
    "forest": ("0x12301a", "FOREST — NPS/USGS (POC/placeholder)"),
    "reef": ("0x06303a", "REEF — NOAA Ocean Exploration (PD placeholder)"),
    "abyss": ("0x021016", "ABYSS — NOAA Ocean Exploration (PD placeholder)"),
}

# Ring edges (adjacent pairs + the abyss->cosmos wrap), matching the manifest.
EDGES = [("cosmos", "orbit"), ("orbit", "forest"), ("forest", "reef"),
         ("reef", "abyss"), ("abyss", "cosmos")]


def _ffmpeg() -> str:
    if shutil.which("ffmpeg"):
        return "ffmpeg"
    import imageio_ffmpeg
    return imageio_ffmpeg.get_ffmpeg_exe()


def _run(args: list[str]) -> None:
    subprocess.run(args, check=True, capture_output=True)


def _make_base(ff: str, name: str, color: str, label: str) -> Path:
    out = MEDIA / name / "base.mp4"
    out.parent.mkdir(parents=True, exist_ok=True)
    # A calm solid tint + faint noise grain (reads as stars/particles), with a
    # placeholder label so it is never mistaken for shipped footage.
    vf = (
        "noise=alls=8:allf=t,"
        "drawtext=text='" + label + "':fontcolor=white@0.55:fontsize=24:"
        "x=(w-text_w)/2:y=h-48"
    )
    _run([
        ff, "-y", "-f", "lavfi", "-i",
        f"color=c={color}:s={SIZE}:d={DUR}:r={FPS}",
        "-vf", vf, "-pix_fmt", "yuv420p", "-an", str(out),
    ])
    return out


def _make_transition(ff: str, src: str, dst: str) -> Path:
    a = MEDIA / src / "base.mp4"
    b = MEDIA / dst / "base.mp4"
    out = MEDIA / "transitions" / f"{src}-{dst}.mp4"
    out.parent.mkdir(parents=True, exist_ok=True)
    w, h = SIZE.split("x")
    # A placeholder zoom/warp morph: zoom-in crossfade from src into dst. Both
    # bases are normalized first (size/fps/sar/format) because the real forest
    # POC base differs in resolution + fps from the synthetic scale placeholders,
    # and xfade requires identical frame geometry on both inputs.
    norm = f"trim=0:3,setpts=PTS-STARTPTS,scale={w}:{h},fps={FPS},setsar=1,format=yuv420p"
    _run([
        ff, "-y", "-i", str(a), "-i", str(b), "-filter_complex",
        f"[0:v]{norm}[a];[1:v]{norm}[b];"
        f"[a][b]xfade=transition=zoomin:duration={XDUR}:offset=0.75,"
        "format=yuv420p[v]",
        "-map", "[v]", "-an", str(out),
    ])
    return out


def main() -> None:
    ff = _ffmpeg()
    for name, (color, label) in SCALES.items():
        base = MEDIA / name / "base.mp4"
        if name == "forest" and base.exists():
            print(f"forest/base.mp4 present (real POC base) — keeping")
            continue
        _make_base(ff, name, color, label)
        print(f"generated {name}/base.mp4 (synthetic placeholder)")
    for src, dst in EDGES:
        _make_transition(ff, src, dst)
        print(f"generated transitions/{src}-{dst}.mp4 (placeholder zoom)")
    print(f"scale-ring media ready in {MEDIA}")


if __name__ == "__main__":
    main()
