// Copyright (c) 2026 Christoph Gaffga
// SPDX-License-Identifier: GPL-3.0-only
// https://github.com/cgaffga/phasmcore
//
// §long-form-stego Phase 6.3 — v2 (interleaved Phase B) orchestrator
// round-trip.
//
// The v2 streaming orchestrator emits per-GOP encoder bytes
// incrementally as 4× StreamingViterbiPhaseB drivers run in
// round-robin lockstep. Memory bound: ~250-400 MB at 15-min 1080p
// vs ~3.6 GB for v1 (Phase 5).
//
// **Note on byte-exact equivalence**: a v1-vs-v2 byte-equality
// gate was tried and proved infeasible — v1 ITSELF is non-
// deterministic in-process (latent bug, tracked separately). Both
// v1 and v2 produce different bytes on each run with the same
// inputs, but both decode round-trips correctly. The right Phase
// 6.3 acceptance gate is round-trip + decoder validation, not
// byte-equality with v1.

#![cfg(feature = "cabac-stego")]

use phasm_core::{
    h264_stego_decode_yuv_string_4domain,
    h264_stego_encode_yuv_string_4domain_multigop_streaming_v2,
};

fn load_real_world(name: &str) -> Vec<u8> {
    std::fs::read(format!("test-vectors/video/h264/real-world/{name}"))
        .unwrap_or_else(|_| panic!("missing real-world fixture: {name}"))
}

#[test]
fn v2_orchestrator_roundtrip_64x48_5f_singlegop() {
    let yuv = load_real_world("img4138_64x48_f5.yuv");
    let bytes = h264_stego_encode_yuv_string_4domain_multigop_streaming_v2(
        &yuv, 64, 48, 5, 5, "x", "v2-roundtrip-64",
    )
    .expect("v2 streaming encode");
    let recovered = h264_stego_decode_yuv_string_4domain(&bytes, "v2-roundtrip-64")
        .expect("v2 streaming decode");
    assert_eq!(recovered, "x", "v2 round-trip preserves payload");
}

#[test]
fn v2_orchestrator_roundtrip_128x80_10f_2gops() {
    let yuv = load_real_world("img4138_128x80_f10.yuv");
    let bytes = h264_stego_encode_yuv_string_4domain_multigop_streaming_v2(
        &yuv, 128, 80, 10, 5, "h", "v2-roundtrip-128",
    )
    .expect("v2 streaming encode 2-GOP");
    let recovered = h264_stego_decode_yuv_string_4domain(&bytes, "v2-roundtrip-128")
        .expect("v2 streaming decode 2-GOP");
    assert_eq!(recovered, "h", "v2 2-GOP round-trip preserves payload");
}

/// §long-form-stego Phase 6.4 — 1080p 10-frame round-trip on the
/// calibration fixture generated by
/// `core/test-vectors/video/h264/real-world/source/regen.sh`.
///
/// `#[ignore]`-d so it doesn't run on systems without the personal
/// `IMG_4138.MOV` source. Run explicitly with:
/// ```bash
/// bash core/test-vectors/video/h264/real-world/source/regen.sh
/// cargo test --features cabac-stego --test h264_stego_streaming_orchestrator_v2 \
///     -- --ignored v2_roundtrip_1080p_2gops
/// ```
#[test]
#[ignore = "requires /tmp/img4138_1080p_f10.yuv (run regen.sh first)"]
fn v2_roundtrip_1080p_2gops() {
    let yuv_path = "/tmp/img4138_1080p_f10.yuv";
    let yuv = match std::fs::read(yuv_path) {
        Ok(y) => y,
        Err(e) => {
            eprintln!("Skipping: {yuv_path} ({e})");
            eprintln!(
                "  To regenerate: bash core/test-vectors/video/h264/real-world/source/regen.sh"
            );
            return;
        }
    };
    let bytes = h264_stego_encode_yuv_string_4domain_multigop_streaming_v2(
        &yuv, 1920, 1072, 10, 5, "Phase 6.4 long-form check",
        "v2-1080p-bench",
    )
    .expect("v2 1080p 10f encode");
    let recovered = h264_stego_decode_yuv_string_4domain(&bytes, "v2-1080p-bench")
        .expect("v2 1080p decode");
    assert_eq!(recovered, "Phase 6.4 long-form check");
}
