//! The payload formats of the WAI-native integer codecs ([integer-payloads] §3–§6):
//! `WIV1` (`wai.video.int_motion`, `wai.video.int_hyper`), `WIH1`
//! (`wai.neural.int_hyper`), `WIA1` (`wai.audio.int_codec`) and `WIS1`
//! (`wai.splat.int_codec`). A parser and a writer for each, and the closed list of
//! refusal codes ([`Refusal`]).
//!
//! Every multi-byte field is little-endian. A parser checks the fields in the order
//! the extension lists them and reports the first rule that fails, so two
//! conforming parsers refuse the same bytes with the same code. Every size is
//! formed in `u64` with checked arithmetic and capped by the same constants on
//! every target, `wasm32` included, so a payload is accepted or refused alike
//! everywhere and no parser allocates more than the bytes it holds justify.
//!
//! This file is self-contained: it uses `std`'s `Vec` and nothing from the crate, so
//! the cross-architecture byte-equality crate (`wai/byte-exact-conformance`)
//! `#[path]`-includes it and parses the committed binary vectors with the same code
//! a sink runs.
//!
//! [integer-payloads]: ../../../extensions/integer-payloads.md

/// `WIV1`: integer inter-frame video.
///
/// cbindgen:ignore
pub const MAGIC_WIV1: [u8; 4] = *b"WIV1";
/// `WIH1`: the integer conditional image codec.
///
/// cbindgen:ignore
pub const MAGIC_WIH1: [u8; 4] = *b"WIH1";
/// `WIA1`: the integer learned audio codec.
///
/// cbindgen:ignore
pub const MAGIC_WIA1: [u8; 4] = *b"WIA1";
/// `WIS1`: the integer learned Gaussian-splat attribute codec.
///
/// cbindgen:ignore
pub const MAGIC_WIS1: [u8; 4] = *b"WIS1";
/// The four magics, for telling a payload of another of these formats from one of
/// none ([`Refusal::FormatCapabilityMismatch`] against [`Refusal::BadMagic`]).
///
/// cbindgen:ignore
pub const MAGICS: [[u8; 4]; 4] = [MAGIC_WIV1, MAGIC_WIH1, MAGIC_WIA1, MAGIC_WIS1];
/// The one version this revision defines, for every format.
///
/// cbindgen:ignore
pub const VERSION: u8 = 1;

/// The most elements any one tensor a payload sizes may hold: a frame (`h·w·3`), a
/// `WIV1` motion-vector field (`2·nb·(n_frames − 1)`), a latent, an attribute tensor, a
/// decoded clip's samples. Also the cap on every activation a decode forms on the way
/// ([integer-payloads] §7).
///
/// cbindgen:ignore
pub const MAX_TENSOR: u64 = 1 << 26;
/// The most decoded bytes a whole `WIV1` clip may hold (`n_frames·h·w·3`).
///
/// cbindgen:ignore
pub const MAX_CLIP: u64 = 1 << 30;
/// The most frames a `WIV1` clip may hold.
///
/// cbindgen:ignore
pub const MAX_FRAMES: u64 = 1 << 20;
/// The largest fixed-point scale a payload may declare (`afrac` in `1..=30`).
///
/// cbindgen:ignore
pub const MAX_AFRAC: u8 = 30;
/// The largest magnitude of a per-channel median (`|median_q| ≤ 2^47`).
///
/// cbindgen:ignore
pub const MAX_MEDIAN_Q: i64 = 1 << 47;
/// The bounds on a CDF table's length.
///
/// cbindgen:ignore
pub const CDF_LEN_MIN: usize = 3;
/// cbindgen:ignore
pub const CDF_LEN_MAX: usize = 4097;
/// The total every CDF table ends at (rANS precision 16).
///
/// cbindgen:ignore
pub const CDF_TOTAL: u32 = 1 << 16;
/// The largest residual quantisation step.
///
/// cbindgen:ignore
pub const MAX_Q: u32 = 65_535;

/// Why a payload was refused: the closed list of [integer-payloads] §8. The first
/// rule that fails, in the order the extension gives, is the reason.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
/// cbindgen:ignore
pub enum Refusal {
    /// The payload does not start with any of the four magics (a JSON form does not).
    BadMagic,
    /// The payload is one of the four formats, but not the one the capability pins.
    FormatCapabilityMismatch,
    /// A `WIV1` keyframe kind that does not belong to the capability (0 is
    /// `wai.video.int_motion`'s, 1 is `wai.video.int_hyper`'s).
    KeyframeCapabilityMismatch,
    /// A version this revision does not define.
    Version,
    /// A reserved field that is not zero.
    ReservedNonzero,
    /// A field outside its range.
    FieldRange,
    /// A tensor, a clip or an activation larger than the caps allow.
    TooLarge,
    /// A CDF table that breaks the table rules.
    CdfMalformed,
    /// The payload ends before a field or section it declares, or a rANS stream's
    /// length is not a multiple of 4 or is under 8.
    StreamLength,
    /// A nested `WIH1` whose declared length is not the rest of the payload.
    NestedLength,
    /// Bytes after the last section.
    Trailing,
    /// A rANS stream that ran out before its last symbol.
    StreamExhausted,
    /// A rANS stream that does not end canonically after its last symbol: a word is
    /// left unread, or the state is not `2^31` ([integer-payloads] §2).
    StreamNoncanonical,
    /// A shape the payload declares disagrees with the shape the decode produces.
    GeometryMismatch,
    /// The parameter set does not fit the payload.
    ModelMismatch,
    /// The parameter set does not contain a file the decode reads.
    SetIncomplete,
    /// The capability is not dispatchable (SPEC §4).
    NotDispatchable,
    /// The capability has no integer decode in this build.
    UnsupportedCapability,
    /// A payload of `wai.neural.int_synth` or `wai.neural.int_mlicpp`, whose formats
    /// are defined elsewhere, refused by its decoder.
    PayloadMalformed,
    /// The payload's declared cost exceeds the limit the sink applies before decoding
    /// ([integer-payloads] §7, *Memory and work*): the sink's own policy, so dispatch
    /// moves on.
    CostOverLimit,
}

impl Refusal {
    /// Every refusal, in the order of [integer-payloads] §8.
    ///
    /// cbindgen:ignore
    pub const ALL: [Refusal; 20] = [
        Refusal::BadMagic,
        Refusal::FormatCapabilityMismatch,
        Refusal::KeyframeCapabilityMismatch,
        Refusal::Version,
        Refusal::ReservedNonzero,
        Refusal::FieldRange,
        Refusal::TooLarge,
        Refusal::CdfMalformed,
        Refusal::StreamLength,
        Refusal::NestedLength,
        Refusal::Trailing,
        Refusal::StreamExhausted,
        Refusal::StreamNoncanonical,
        Refusal::GeometryMismatch,
        Refusal::ModelMismatch,
        Refusal::SetIncomplete,
        Refusal::NotDispatchable,
        Refusal::UnsupportedCapability,
        Refusal::PayloadMalformed,
        Refusal::CostOverLimit,
    ];

    /// The code [integer-payloads] §8 names.
    pub fn code(self) -> &'static str {
        match self {
            Refusal::BadMagic => "bad_magic",
            Refusal::FormatCapabilityMismatch => "format_capability_mismatch",
            Refusal::KeyframeCapabilityMismatch => "keyframe_capability_mismatch",
            Refusal::Version => "version",
            Refusal::ReservedNonzero => "reserved_nonzero",
            Refusal::FieldRange => "field_range",
            Refusal::TooLarge => "too_large",
            Refusal::CdfMalformed => "cdf_malformed",
            Refusal::StreamLength => "stream_length",
            Refusal::NestedLength => "nested_length",
            Refusal::Trailing => "trailing",
            Refusal::StreamExhausted => "stream_exhausted",
            Refusal::StreamNoncanonical => "stream_noncanonical",
            Refusal::GeometryMismatch => "geometry_mismatch",
            Refusal::ModelMismatch => "model_mismatch",
            Refusal::SetIncomplete => "set_incomplete",
            Refusal::NotDispatchable => "not_dispatchable",
            Refusal::UnsupportedCapability => "unsupported_capability",
            Refusal::PayloadMalformed => "payload_malformed",
            Refusal::CostOverLimit => "cost_over_limit",
        }
    }

    /// The refusal whose code is `code`.
    pub fn from_code(code: &str) -> Option<Refusal> {
        Refusal::ALL.into_iter().find(|r| r.code() == code)
    }
}

/// A parser's refusal: the code and what failed.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WireError {
    pub refusal: Refusal,
    pub detail: &'static str,
}

impl WireError {
    /// cbindgen:ignore
    pub const fn new(refusal: Refusal, detail: &'static str) -> Self {
        WireError { refusal, detail }
    }
    pub fn code(&self) -> &'static str {
        self.refusal.code()
    }
}

impl std::fmt::Display for WireError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}: {}", self.refusal.code(), self.detail)
    }
}

impl std::error::Error for WireError {}

const fn err(refusal: Refusal, detail: &'static str) -> WireError {
    WireError { refusal, detail }
}

/// The magic check every parser starts with: `want` passes; another of the four
/// magics is the wrong format for the capability; anything else, a JSON form
/// included, is not one of these formats.
pub fn check_magic(p: &[u8], want: [u8; 4]) -> Result<(), WireError> {
    match p.get(0..4) {
        Some(m) if m == want => Ok(()),
        Some(m) if MAGICS.iter().any(|k| k[..] == *m) => {
            Err(err(Refusal::FormatCapabilityMismatch, "the payload is another integer format than the capability's"))
        }
        _ => Err(err(Refusal::BadMagic, "the payload does not start with the capability's magic")),
    }
}

/// The table rules every CDF obeys ([integer-payloads] §7): `3 ≤ len ≤ 4097`,
/// `cdf[0] = 0`, `cdf[len−1] = 2^16`, strictly increasing. They are the
/// precondition under which the rANS decoder's symbol search and state update stay
/// in range.
pub fn check_cdf(cdf: &[i32]) -> Result<(), WireError> {
    if cdf.len() < CDF_LEN_MIN || cdf.len() > CDF_LEN_MAX {
        return Err(err(Refusal::CdfMalformed, "a CDF table's length is outside 3..=4097"));
    }
    if cdf[0] != 0 || cdf[cdf.len() - 1] != CDF_TOTAL as i32 {
        return Err(err(Refusal::CdfMalformed, "a CDF table does not run from 0 to 65536"));
    }
    if cdf.windows(2).any(|w| w[0] >= w[1]) {
        return Err(err(Refusal::CdfMalformed, "a CDF table is not strictly increasing"));
    }
    Ok(())
}

/// The product of `dims` in `u64`, or `None` past `u64`.
fn product(dims: &[u64]) -> Option<u64> {
    dims.iter().try_fold(1u64, |a, &d| a.checked_mul(d))
}

/// A product checked against `cap`: [`Refusal::TooLarge`] past it (or past `u64`).
fn capped(dims: &[u64], cap: u64, detail: &'static str) -> Result<u64, WireError> {
    product(dims).filter(|&n| n <= cap).ok_or(err(Refusal::TooLarge, detail))
}

/// A bounds-checked little-endian reader. Every read past the end is
/// [`Refusal::StreamLength`].
struct Cur<'a> {
    b: &'a [u8],
    p: usize,
}

impl<'a> Cur<'a> {
    fn new(b: &'a [u8], p: usize) -> Self {
        Cur { b, p }
    }
    fn left(&self) -> usize {
        self.b.len() - self.p
    }
    /// The next `n` bytes; `n` is a `u64` the caller formed, so no allocation or
    /// slice is ever sized from more than the payload holds.
    fn take(&mut self, n: u64, what: &'static str) -> Result<&'a [u8], WireError> {
        let n = usize::try_from(n).ok().filter(|&n| n <= self.left()).ok_or(err(Refusal::StreamLength, what))?;
        let s = &self.b[self.p..self.p + n];
        self.p += n;
        Ok(s)
    }
    fn u8(&mut self, what: &'static str) -> Result<u8, WireError> {
        Ok(self.take(1, what)?[0])
    }
    fn u16(&mut self, what: &'static str) -> Result<u16, WireError> {
        let s = self.take(2, what)?;
        Ok(u16::from_le_bytes([s[0], s[1]]))
    }
    fn u32(&mut self, what: &'static str) -> Result<u32, WireError> {
        let s = self.take(4, what)?;
        Ok(u32::from_le_bytes([s[0], s[1], s[2], s[3]]))
    }
    fn i32(&mut self, what: &'static str) -> Result<i32, WireError> {
        Ok(self.u32(what)? as i32)
    }
    /// A CDF table of `len` `u32` entries, read and checked.
    fn cdf(&mut self, len: u64, what: &'static str) -> Result<Vec<i32>, WireError> {
        let s = self.take(len.checked_mul(4).unwrap_or(u64::MAX), what)?;
        let cdf: Vec<i32> = s
            .chunks_exact(4)
            .map(|c| u32::from_le_bytes([c[0], c[1], c[2], c[3]]))
            .map(|v| i32::try_from(v).unwrap_or(i32::MAX))
            .collect();
        check_cdf(&cdf)?;
        Ok(cdf)
    }
    /// A length-prefixed rANS stream: `u32 L` then `L` bytes, `L` a multiple of 4
    /// and at least 8.
    fn stream(&mut self, what: &'static str) -> Result<&'a [u8], WireError> {
        let len = self.u32(what)?;
        if len % 4 != 0 || len < 8 {
            return Err(err(Refusal::StreamLength, "a rANS stream's length is not a multiple of 4, or is under 8"));
        }
        self.take(len as u64, what)
    }
    /// Nothing may follow the last section.
    fn end(&self) -> Result<(), WireError> {
        if self.left() != 0 {
            return Err(err(Refusal::Trailing, "bytes follow the last section"));
        }
        Ok(())
    }
}

/// The checks every format opens with: the magic, then the version byte at offset
/// 4, then a fixed header of `header` bytes.
fn open<'a>(p: &'a [u8], magic: [u8; 4], header: usize) -> Result<Cur<'a>, WireError> {
    check_magic(p, magic)?;
    let version = *p.get(4).ok_or(err(Refusal::StreamLength, "the payload ends before its version"))?;
    if version != VERSION {
        return Err(err(Refusal::Version, "a version this revision does not define"));
    }
    if p.len() < header {
        return Err(err(Refusal::StreamLength, "the payload ends inside its fixed header"));
    }
    Ok(Cur::new(p, 5))
}

fn put_u16(o: &mut Vec<u8>, v: u16) {
    o.extend_from_slice(&v.to_le_bytes());
}
fn put_u32(o: &mut Vec<u8>, v: u32) {
    o.extend_from_slice(&v.to_le_bytes());
}
fn put_i32(o: &mut Vec<u8>, v: i32) {
    o.extend_from_slice(&v.to_le_bytes());
}
fn put_i64(o: &mut Vec<u8>, v: i64) {
    o.extend_from_slice(&v.to_le_bytes());
}
fn put_cdf(o: &mut Vec<u8>, cdf: &[i32]) {
    for &v in cdf {
        put_u32(o, v as u32);
    }
}
fn put_stream(o: &mut Vec<u8>, s: &[u8]) {
    put_u32(o, s.len() as u32);
    o.extend_from_slice(s);
}

// ───────────────────────────── WIV1 ─────────────────────────────

/// A parsed `WIV1` payload ([integer-payloads] §3).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Wiv1<'a> {
    /// `1` whole-pel, `2` half-pel: a motion vector is in units of `1/mv_precision` pel.
    pub mv_precision: u8,
    /// `0`: the first frame is predicted from grey and coded in the residual stream
    /// (`wai.video.int_motion`). `1`: the first frame is the nested `WIH1`'s decode
    /// (`wai.video.int_hyper`).
    pub keyframe: u8,
    pub n_frames: u32,
    pub h: u32,
    pub w: u32,
    pub block: u32,
    pub q: u32,
    pub offset: i32,
    pub cdf: Vec<i32>,
    /// Frames `1..n_frames`, each its block grid row-major: `(dy, dx)` per block,
    /// `nb = ⌈h/block⌉·⌈w/block⌉` per frame.
    pub mvs: Vec<(i16, i16)>,
    /// The residual rANS stream.
    pub rans: &'a [u8],
    /// The nested `WIH1` payload, when `keyframe` is 1.
    pub wih1: Option<&'a [u8]>,
}

/// `WIV1`'s fixed header, in bytes.
///
/// cbindgen:ignore
pub const WIV1_HEADER: usize = 36;

impl Wiv1<'_> {
    /// Blocks per frame: `⌈h/block⌉·⌈w/block⌉`.
    pub fn blocks_per_frame(&self) -> u64 {
        blocks(self.h, self.w, self.block)
    }

    /// The most bytes the reference decode of a keyframe-0 clip holds at once beyond
    /// the payload ([integer-payloads] §7, *Memory and work*): its table and motion
    /// vectors as parsed (4 bytes an entry), the clip (one byte per sample) and its
    /// frame list (one `Vec` header per frame). The header alone fixes it; a keyframe-1
    /// clip also runs its keyframe's networks, which the parameter set sizes.
    pub fn keyframe0_working_bytes(&self) -> u64 {
        let clip = self.h as u64 * self.w as u64 * 3 * self.n_frames as u64;
        4 * self.cdf.len() as u64 + 4 * self.mvs.len() as u64 + clip
            + std::mem::size_of::<Vec<u8>>() as u64 * self.n_frames as u64
    }
}

fn blocks(h: u32, w: u32, block: u32) -> u64 {
    (h as u64).div_ceil(block.max(1) as u64) * (w as u64).div_ceil(block.max(1) as u64)
}

/// Parse a `WIV1` payload. `want_keyframe` is the keyframe kind the capability
/// pins (`Some(0)` for `wai.video.int_motion`, `Some(1)` for `wai.video.int_hyper`);
/// `None` accepts either.
pub fn parse_wiv1(p: &[u8], want_keyframe: Option<u8>) -> Result<Wiv1<'_>, WireError> {
    let mut c = open(p, MAGIC_WIV1, WIV1_HEADER)?;
    let mv_precision = c.u8("mv_precision")?;
    let keyframe = c.u8("keyframe")?;
    let reserved0 = c.u8("reserved")?;
    let n_frames = c.u32("n_frames")?;
    let h = c.u32("h")?;
    let w = c.u32("w")?;
    let block = c.u32("block")?;
    let q = c.u32("q")?;
    let offset = c.i32("offset")?;
    let cdf_len = c.u16("cdf_len")?;
    let reserved1 = c.u16("reserved")?;
    if reserved0 != 0 || reserved1 != 0 {
        return Err(err(Refusal::ReservedNonzero, "a reserved field is not zero"));
    }
    if !matches!(mv_precision, 1 | 2) {
        return Err(err(Refusal::FieldRange, "mv_precision is neither 1 nor 2"));
    }
    if keyframe > 1 {
        return Err(err(Refusal::FieldRange, "keyframe is neither 0 nor 1"));
    }
    if n_frames == 0 || h == 0 || w == 0 {
        return Err(err(Refusal::FieldRange, "n_frames, h or w is zero"));
    }
    if block == 0 {
        return Err(err(Refusal::FieldRange, "block is zero"));
    }
    if q == 0 || q > MAX_Q {
        return Err(err(Refusal::FieldRange, "q is outside 1..=65535"));
    }
    if (cdf_len as usize) < CDF_LEN_MIN || cdf_len as usize > CDF_LEN_MAX {
        return Err(err(Refusal::FieldRange, "cdf_len is outside 3..=4097"));
    }
    // A one-frame clip codes no motion vector, so neither field would change its
    // decode; they are fixed so that such a clip has one header.
    if n_frames == 1 && (mv_precision != 1 || block != 1) {
        return Err(err(Refusal::FieldRange, "a one-frame clip has mv_precision 1 and block 1"));
    }
    if let Some(k) = want_keyframe {
        if k != keyframe {
            return Err(err(Refusal::KeyframeCapabilityMismatch, "the keyframe kind is not the capability's"));
        }
    }
    capped(&[h as u64, w as u64, 3], MAX_TENSOR, "a frame exceeds 2^26 elements")?;
    capped(&[n_frames as u64, h as u64, w as u64, 3], MAX_CLIP, "the clip exceeds 2^30 bytes")?;
    capped(&[n_frames as u64], MAX_FRAMES, "the clip exceeds 2^20 frames")?;
    let n_mv = capped(&[2, n_frames as u64 - 1, blocks(h, w, block)], MAX_TENSOR, "the motion vectors exceed 2^26 elements")? / 2;
    let cdf = c.cdf(cdf_len as u64, "the CDF table")?;
    let raw = c.take(n_mv.checked_mul(4).unwrap_or(u64::MAX), "the motion vectors")?;
    let mvs = raw
        .chunks_exact(4)
        .map(|m| (i16::from_le_bytes([m[0], m[1]]), i16::from_le_bytes([m[2], m[3]])))
        .collect();
    let rans = c.stream("the residual stream")?;
    let wih1 = if keyframe == 1 {
        let k = c.u32("the keyframe length")?;
        if k as usize != c.left() {
            return Err(err(Refusal::NestedLength, "the keyframe length is not the rest of the payload"));
        }
        let nested = c.take(k as u64, "the keyframe")?;
        parse_wih1(nested)?;
        Some(nested)
    } else {
        c.end()?;
        None
    };
    Ok(Wiv1 { mv_precision, keyframe, n_frames, h, w, block, q, offset, cdf, mvs, rans, wih1 })
}

/// Write a `WIV1` payload. The caller supplies conforming fields; the converters
/// parse what they write before returning it.
pub fn write_wiv1(v: &Wiv1<'_>) -> Vec<u8> {
    let mut o = Vec::with_capacity(WIV1_HEADER + v.cdf.len() * 4 + v.mvs.len() * 4 + v.rans.len() + 8);
    o.extend_from_slice(&MAGIC_WIV1);
    o.extend_from_slice(&[VERSION, v.mv_precision, v.keyframe, 0]);
    put_u32(&mut o, v.n_frames);
    put_u32(&mut o, v.h);
    put_u32(&mut o, v.w);
    put_u32(&mut o, v.block);
    put_u32(&mut o, v.q);
    put_i32(&mut o, v.offset);
    put_u16(&mut o, v.cdf.len() as u16);
    put_u16(&mut o, 0);
    put_cdf(&mut o, &v.cdf);
    for &(dy, dx) in &v.mvs {
        o.extend_from_slice(&dy.to_le_bytes());
        o.extend_from_slice(&dx.to_le_bytes());
    }
    put_stream(&mut o, v.rans);
    if let Some(k) = v.wih1 {
        put_stream(&mut o, k);
    }
    o
}

// ───────────────────────────── WIH1 ─────────────────────────────

/// A parsed `WIH1` payload ([integer-payloads] §4): the conditional codec's two
/// streams and the shapes of its two latents.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Wih1<'a> {
    /// Latent `y`: `m` channels of `sh × sw`.
    pub m: u32,
    pub sh: u32,
    pub sw: u32,
    /// Hyper-latent `z`: `n_z` channels of `zh × zw`.
    pub n_z: u32,
    pub zh: u32,
    pub zw: u32,
    /// The factorized-prior stream of `z`.
    pub z_rans: &'a [u8],
    /// The Gaussian-conditional stream of `y`.
    pub rans: &'a [u8],
}

/// `WIH1`'s fixed header, in bytes.
///
/// cbindgen:ignore
pub const WIH1_HEADER: usize = 32;

/// Parse a `WIH1` payload.
pub fn parse_wih1(p: &[u8]) -> Result<Wih1<'_>, WireError> {
    let mut c = open(p, MAGIC_WIH1, WIH1_HEADER)?;
    let reserved = c.take(3, "reserved")?;
    let m = c.u32("m")?;
    let sh = c.u32("sh")?;
    let sw = c.u32("sw")?;
    let n_z = c.u32("n_z")?;
    let zh = c.u32("zh")?;
    let zw = c.u32("zw")?;
    if reserved.iter().any(|&b| b != 0) {
        return Err(err(Refusal::ReservedNonzero, "a reserved field is not zero"));
    }
    if [m, sh, sw, n_z, zh, zw].contains(&0) {
        return Err(err(Refusal::FieldRange, "a latent dimension is zero"));
    }
    capped(&[n_z as u64, zh as u64, zw as u64], MAX_TENSOR, "the hyper-latent exceeds 2^26 elements")?;
    capped(&[2, m as u64, sh as u64, sw as u64], MAX_TENSOR, "the latent's mean and scale exceed 2^26 elements")?;
    let z_rans = c.stream("the z stream")?;
    let rans = c.stream("the y stream")?;
    c.end()?;
    Ok(Wih1 { m, sh, sw, n_z, zh, zw, z_rans, rans })
}

/// Write a `WIH1` payload.
pub fn write_wih1(v: &Wih1<'_>) -> Vec<u8> {
    let mut o = Vec::with_capacity(WIH1_HEADER + v.z_rans.len() + v.rans.len() + 8);
    o.extend_from_slice(&MAGIC_WIH1);
    o.extend_from_slice(&[VERSION, 0, 0, 0]);
    for d in [v.m, v.sh, v.sw, v.n_z, v.zh, v.zw] {
        put_u32(&mut o, d);
    }
    put_stream(&mut o, v.z_rans);
    put_stream(&mut o, v.rans);
    o
}

// ───────────────────────────── WIA1 ─────────────────────────────

/// A parsed `WIA1` payload ([integer-payloads] §5).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Wia1<'a> {
    /// The fixed-point scale; it must equal the model's.
    pub afrac: u8,
    /// The sample rate the PCM is presented at, in hertz.
    pub sr: u32,
    /// Latent channels and length.
    pub n_ch: u32,
    pub lat_len: u32,
    /// Samples presented: the first `t_out` of the synthesis.
    pub t_out: u32,
    /// The symbol offset every channel's table is coded at.
    pub offset: i32,
    pub median_q: Vec<i64>,
    /// One table per channel, all of one length.
    pub cdfs: Vec<Vec<i32>>,
    pub rans: &'a [u8],
}

/// `WIA1`'s fixed header, in bytes.
///
/// cbindgen:ignore
pub const WIA1_HEADER: usize = 32;

/// Parse a `WIA1` payload.
pub fn parse_wia1(p: &[u8]) -> Result<Wia1<'_>, WireError> {
    let mut c = open(p, MAGIC_WIA1, WIA1_HEADER)?;
    let afrac = c.u8("afrac")?;
    let reserved0 = c.u16("reserved")?;
    let sr = c.u32("sr")?;
    let n_ch = c.u32("n_ch")?;
    let lat_len = c.u32("lat_len")?;
    let t_out = c.u32("t_out")?;
    let offset = c.i32("offset")?;
    let cdf_len = c.u16("cdf_len")?;
    let reserved1 = c.u16("reserved")?;
    if reserved0 != 0 || reserved1 != 0 {
        return Err(err(Refusal::ReservedNonzero, "a reserved field is not zero"));
    }
    if afrac == 0 || afrac > MAX_AFRAC {
        return Err(err(Refusal::FieldRange, "afrac is outside 1..=30"));
    }
    if sr == 0 || n_ch == 0 || lat_len == 0 || t_out == 0 {
        return Err(err(Refusal::FieldRange, "sr, n_ch, lat_len or t_out is zero"));
    }
    if (cdf_len as usize) < CDF_LEN_MIN || cdf_len as usize > CDF_LEN_MAX {
        return Err(err(Refusal::FieldRange, "cdf_len is outside 3..=4097"));
    }
    capped(&[n_ch as u64, lat_len as u64], MAX_TENSOR, "the latent exceeds 2^26 elements")?;
    capped(&[t_out as u64], MAX_TENSOR, "t_out exceeds 2^26 samples")?;
    let raw = c.take(n_ch as u64 * 8, "the medians")?;
    let median_q: Vec<i64> = raw.chunks_exact(8).map(|b| i64::from_le_bytes(b.try_into().unwrap())).collect();
    if median_q.iter().any(|m| m.unsigned_abs() > MAX_MEDIAN_Q as u64) {
        return Err(err(Refusal::FieldRange, "a median's magnitude exceeds 2^47"));
    }
    let mut cdfs = Vec::with_capacity(n_ch as usize);
    for _ in 0..n_ch {
        cdfs.push(c.cdf(cdf_len as u64, "the CDF tables")?);
    }
    let rans = c.stream("the latent stream")?;
    c.end()?;
    Ok(Wia1 { afrac, sr, n_ch, lat_len, t_out, offset, median_q, cdfs, rans })
}

/// Write a `WIA1` payload.
pub fn write_wia1(v: &Wia1<'_>) -> Vec<u8> {
    let cdf_len = v.cdfs.first().map_or(0, Vec::len);
    let mut o = Vec::with_capacity(WIA1_HEADER + v.median_q.len() * 8 + v.cdfs.len() * cdf_len * 4 + v.rans.len() + 4);
    o.extend_from_slice(&MAGIC_WIA1);
    o.extend_from_slice(&[VERSION, v.afrac, 0, 0]);
    put_u32(&mut o, v.sr);
    put_u32(&mut o, v.n_ch);
    put_u32(&mut o, v.lat_len);
    put_u32(&mut o, v.t_out);
    put_i32(&mut o, v.offset);
    put_u16(&mut o, cdf_len as u16);
    put_u16(&mut o, 0);
    for &m in &v.median_q {
        put_i64(&mut o, m);
    }
    for cdf in &v.cdfs {
        put_cdf(&mut o, cdf);
    }
    put_stream(&mut o, v.rans);
    o
}

// ───────────────────────────── WIS1 ─────────────────────────────

/// An IEEE 754 binary32 value held as its bits, as `WIS1` carries a presentation range
/// ([integer-payloads] §6). A parser reads, checks and writes it in integer arithmetic,
/// so no floating-point operation is on a payload's decode path; a sink that presents
/// the range takes its value from the bits (`f32::from_bits`).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Binary32(pub u32);

impl Binary32 {
    /// Finite: the exponent field is not all ones (neither an infinity nor a NaN).
    pub fn is_finite(self) -> bool {
        self.0 & 0x7f80_0000 != 0x7f80_0000
    }

    /// `self ≤ other` as IEEE 754 compares two finite values, `−0` equal to `+0`: by the
    /// magnitude's bits, negated for a negative value (a finite magnitude's bits are
    /// below `2^31 − 2^23`, so the negation stays in `i32`).
    pub fn finite_le(self, other: Binary32) -> bool {
        let key = |b: Binary32| {
            let m = (b.0 & 0x7fff_ffff) as i32;
            if b.0 >> 31 == 1 { -m } else { m }
        };
        key(self) <= key(other)
    }
}

/// A parsed `WIS1` payload ([integer-payloads] §6).
#[derive(Debug, Clone, PartialEq)]
pub struct Wis1<'a> {
    /// The fixed-point scale; it must equal the model's.
    pub afrac: u8,
    /// Latent: `c` channels of `sh × sw`.
    pub c: u32,
    pub sh: u32,
    pub sw: u32,
    /// The attribute tensor: `attr` planes of `s × s`.
    pub s: u32,
    pub attr: u32,
    /// Gaussians in the cloud: the first `n_gaussians` cells of each plane.
    pub n_gaussians: u32,
    /// Per attribute, the range `(lo, hi)` its `u8` plane is presented over, as
    /// binary32 bits. Presentation only: outside the splat-equivalence digest.
    pub ranges: Vec<(Binary32, Binary32)>,
    /// Per channel, its table, its symbol offset and its median.
    pub cdfs: Vec<Vec<i32>>,
    pub offsets: Vec<i32>,
    pub median_q: Vec<i64>,
    pub rans: &'a [u8],
}

/// `WIS1`'s fixed header, in bytes.
///
/// cbindgen:ignore
pub const WIS1_HEADER: usize = 32;

/// Parse a `WIS1` payload.
pub fn parse_wis1(p: &[u8]) -> Result<Wis1<'_>, WireError> {
    let mut cur = open(p, MAGIC_WIS1, WIS1_HEADER)?;
    let afrac = cur.u8("afrac")?;
    let reserved = cur.u16("reserved")?;
    let c = cur.u32("c")?;
    let sh = cur.u32("sh")?;
    let sw = cur.u32("sw")?;
    let s = cur.u32("s")?;
    let attr = cur.u32("attr")?;
    let n_gaussians = cur.u32("n_gaussians")?;
    if reserved != 0 {
        return Err(err(Refusal::ReservedNonzero, "a reserved field is not zero"));
    }
    if afrac == 0 || afrac > MAX_AFRAC {
        return Err(err(Refusal::FieldRange, "afrac is outside 1..=30"));
    }
    if [c, sh, sw, s, attr, n_gaussians].contains(&0) {
        return Err(err(Refusal::FieldRange, "a dimension is zero"));
    }
    if n_gaussians as u64 > s as u64 * s as u64 {
        return Err(err(Refusal::FieldRange, "n_gaussians exceeds s·s"));
    }
    capped(&[c as u64, sh as u64, sw as u64], MAX_TENSOR, "the latent exceeds 2^26 elements")?;
    capped(&[attr as u64, s as u64, s as u64], MAX_TENSOR, "the attribute tensor exceeds 2^26 elements")?;
    let raw = cur.take(attr as u64 * 8, "the attribute ranges")?;
    let mut ranges = Vec::with_capacity(attr as usize);
    for r in raw.chunks_exact(8) {
        let lo = Binary32(u32::from_le_bytes([r[0], r[1], r[2], r[3]]));
        let hi = Binary32(u32::from_le_bytes([r[4], r[5], r[6], r[7]]));
        if !(lo.is_finite() && hi.is_finite() && lo.finite_le(hi)) {
            return Err(err(Refusal::FieldRange, "an attribute range is not finite, or its lo exceeds its hi"));
        }
        ranges.push((lo, hi));
    }
    let raw = cur.take(c as u64 * 2, "the CDF lengths")?;
    let lens: Vec<u16> = raw.chunks_exact(2).map(|b| u16::from_le_bytes([b[0], b[1]])).collect();
    if lens.iter().any(|&l| (l as usize) < CDF_LEN_MIN || l as usize > CDF_LEN_MAX) {
        return Err(err(Refusal::FieldRange, "a CDF length is outside 3..=4097"));
    }
    let raw = cur.take(c as u64 * 4, "the symbol offsets")?;
    let offsets = raw.chunks_exact(4).map(|b| i32::from_le_bytes([b[0], b[1], b[2], b[3]])).collect();
    let raw = cur.take(c as u64 * 8, "the medians")?;
    let median_q: Vec<i64> = raw.chunks_exact(8).map(|b| i64::from_le_bytes(b.try_into().unwrap())).collect();
    if median_q.iter().any(|m| m.unsigned_abs() > MAX_MEDIAN_Q as u64) {
        return Err(err(Refusal::FieldRange, "a median's magnitude exceeds 2^47"));
    }
    let mut cdfs = Vec::with_capacity(c as usize);
    for &l in &lens {
        cdfs.push(cur.cdf(l as u64, "the CDF tables")?);
    }
    let rans = cur.stream("the latent stream")?;
    cur.end()?;
    Ok(Wis1 { afrac, c, sh, sw, s, attr, n_gaussians, ranges, cdfs, offsets, median_q, rans })
}

/// Write a `WIS1` payload.
pub fn write_wis1(v: &Wis1<'_>) -> Vec<u8> {
    let mut o = Vec::with_capacity(WIS1_HEADER + v.ranges.len() * 8 + v.rans.len() + 64);
    o.extend_from_slice(&MAGIC_WIS1);
    o.extend_from_slice(&[VERSION, v.afrac, 0, 0]);
    for d in [v.c, v.sh, v.sw, v.s, v.attr, v.n_gaussians] {
        put_u32(&mut o, d);
    }
    for &(lo, hi) in &v.ranges {
        put_u32(&mut o, lo.0);
        put_u32(&mut o, hi.0);
    }
    for cdf in &v.cdfs {
        put_u16(&mut o, cdf.len() as u16);
    }
    for &off in &v.offsets {
        put_i32(&mut o, off);
    }
    for &m in &v.median_q {
        put_i64(&mut o, m);
    }
    for cdf in &v.cdfs {
        put_cdf(&mut o, cdf);
    }
    put_stream(&mut o, v.rans);
    o
}
