"""Independently decode published files and verify the stored-luma measurements."""

import csv
import hashlib
import json
import subprocess
import sys
from pathlib import Path

import numpy as np
from PIL import Image

root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).parent
report = json.loads((root / "compression-measurements.json").read_text())
arrays = {}
raws = {}
for row in report["records"]:
    path = root / row["file"]
    assert len(path.read_bytes()) == row["bytes"]
    # A rerendered Matroska container can carry a different container identifier
    if len(sys.argv) < 3:
        assert hashlib.sha256(path.read_bytes()).hexdigest() == row["sha256"]
    raw = subprocess.check_output(
        ["ffmpeg", "-v", "error", "-i", str(path), "-f", "rawvideo", "-pix_fmt", "yuv420p", "-"]
    )
    assert len(raw) == 72 * 640 * 360 * 3 // 2
    raws[row["file"]] = raw
    arrays[row["file"]] = (
        np.frombuffer(raw, dtype=np.uint8).reshape(72, 345600)[:, :230400].reshape(72, 360, 640)
    )
base = arrays["compression-source.mkv"]
assert hashlib.sha256(raws["compression-source.mkv"]).hexdigest() == report["rawSHA256"]
for row in report["records"]:
    a = arrays[row["file"]]
    per = np.abs(a.astype(np.int16) - base.astype(np.int16)).mean(axis=(1, 2))
    assert np.allclose(per, row["perFrameLumaError"], rtol=0, atol=1e-12)
    assert abs(float(per.mean()) - row["meanAbsoluteStoredLumaError"]) < 1e-12
    prefix = row["file"].rsplit(".", 1)[0]
    assert np.array_equal(np.asarray(Image.open(root / f"{prefix}-luma-frame.png")), a[36])
    crop = np.repeat(np.repeat(a[36, 120:264, 352:544], 3, axis=0), 3, axis=1)
    assert np.array_equal(np.asarray(Image.open(root / f"{prefix}-luma-crop.png")), crop)
with (root / "compression-measurements.csv").open() as handle:
    for csvrow, r in zip(csv.DictReader(handle), report["records"], strict=True):
        assert (
            int(csvrow["bytes"]) == r["bytes"]
            and abs(
                float(csvrow["mean_absolute_stored_luma_error"]) - r["meanAbsoluteStoredLumaError"]
            )
            < 1e-12
        )
print(
    json.dumps(
        {
            "decodedFiles": 3,
            "decodedFramesPerFile": 72,
            "durationSeconds": 3,
            "checkedStoredLumaSamplesPerFile": 16588800,
            "losslessSourceMatchesAuthoredRawSHA": True,
            "savedFramesAndCropsMatch": True,
            "scope": "Numeric decoded sample verification not a perceptual detector or source authenticity score",
        },
        indent=2,
    )
)
