#!/usr/bin/env python3
"""Verify the current WLK/MLK restoration contract."""
from __future__ import annotations

import json
import wave
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "out"


def require(condition: bool, message: str) -> None:
    if not condition:
        raise ValueError(message)


def load_manifest() -> dict:
    path = OUT / "audio_archive_manifest.json"
    require(path.exists(), "missing out/audio_archive_manifest.json")
    data = json.loads(path.read_text(encoding="utf-8"))
    require(data.get("source") == "audio archive manifest", "manifest source mismatch")
    require(data.get("status") == "verified", "manifest status is not verified")
    return data


def verify_wlk(manifest: dict) -> None:
    wlk = manifest.get("wlk") or {}
    entries = wlk.get("entries") or []
    require(wlk.get("count") == 54, "WLK count should be 54")
    require(wlk.get("verifiedCount") == 54, "WLK verified count should be 54")
    require(wlk.get("bitDepthCounts", {}).get("16-bit") == 7, "WLK 16-bit count should be 7")
    require(wlk.get("bitDepthCounts", {}).get("8-bit") == 47, "WLK 8-bit count should be 47")
    require(wlk.get("flagCounts", {}).get("0x20") == 4, "WLK loop flag count should be 4")
    require(len(entries) == 54, "WLK entries length should be 54")

    wlk_44 = entries[44]
    wlk_45 = entries[45]
    require(wlk_44.get("exeId") == "44", "WLK id 44 row missing")
    require(wlk_44.get("sampleRate") == 11025, "WLK id 44 sample rate should be 11025")
    require(wlk_44.get("bitDepth") == 8, "WLK id 44 bit depth should be 8")
    require(wlk_44.get("gain") == -500, "WLK id 44 gain should be -500")
    require(wlk_45.get("exeId") == "45", "WLK id 45 row missing")
    require(wlk_45.get("gain") == -1800, "WLK id 45 gain should be -1800")

    for entry in entries:
        wav_path = ROOT / entry["file"]
        require(wav_path.exists(), f"missing {entry['file']}")
        with wave.open(str(wav_path), "rb") as wav:
            require(wav.getnchannels() == entry["channels"], f"{entry['file']} channel mismatch")
            require(wav.getsampwidth() == entry["bitDepth"] // 8, f"{entry['file']} bit depth mismatch")
            require(wav.getframerate() == entry["sampleRate"], f"{entry['file']} sample rate mismatch")


def verify_mlk(manifest: dict) -> None:
    mlk = manifest.get("mlk") or {}
    entries = mlk.get("entries") or []
    require(mlk.get("count") == 20, "MLK count should be 20")
    require(mlk.get("verifiedCount") == 20, "MLK verified count should be 20")
    require(mlk.get("formatCounts", {}).get("0") == 20, "MLK SMF format 0 count should be 20")
    require(len(entries) == 20, "MLK entries length should be 20")
    for entry in entries:
        midi_path = ROOT / entry["file"]
        require(midi_path.exists(), f"missing {entry['file']}")
        require(midi_path.read_bytes()[:4] == b"MThd", f"{entry['file']} is not SMF")


def verify_web_surfaces() -> None:
    removed_paths = [
        OUT / "wlk_audio_probe.json",
        OUT / "wlk_audio_probe.md",
        OUT / "wlk_audio_probe.html",
        OUT / "wlk_audio_probe",
    ]
    for path in removed_paths:
        require(not path.exists(), f"old WLK probe output still exists: {path}")

    web_files = [
        ROOT / "web" / "audio_review.html",
        ROOT / "web" / "midi_bgm_test.html",
        ROOT / "web" / "index.html",
        ROOT / "web" / "progress.html",
        ROOT / "web" / "format_review.html",
        ROOT / "web" / "game.html",
    ]
    for path in web_files:
        text = path.read_text(encoding="utf-8")
        require("wlk_audio_probe" not in text, f"{path.relative_to(ROOT)} still references wlk_audio_probe")
        require("45_s16-browser-audible-preview" not in text, f"{path.relative_to(ROOT)} still references WLK45 preview")

    audio_review = (ROOT / "web" / "audio_review.html").read_text(encoding="utf-8")
    for marker in [
        "audio_archive_manifest.json",
        "audioArchiveRestorationComplete",
        "browserWlkProbeRemoved",
        "wlkIds=",
        "engine/audio/midi_bgm_player.js GM Lite synth + optional SF2/SF3/Web MIDI path.",
        "midi_bgm_test_browser_smoke.json",
    ]:
        require(marker in audio_review, f"audio_review.html missing marker {marker}")


def main() -> None:
    manifest = load_manifest()
    verify_wlk(manifest)
    verify_mlk(manifest)
    verify_web_surfaces()
    print("audio archive manifest verified")


if __name__ == "__main__":
    main()
