// Component contract for the client upstream bundling path.
//
// Scope: protect the client-side media component that joins live audio and
// encoded video before transport.
// Targets: `client/src/app/uplink_media/*.rs`.
// Why: the current sync win depends on sending related audio and video together
// while still dropping stale backlog, so the component wiring must not regress.

const BUNDLED_QUEUE: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/app/uplink_media/bundled_media_queue.rs"
));
const WEBCAM_LOOP: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/app/uplink_media/webcam_media_loop.rs"
));
const VIDEO_KEYFRAMES: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/app/uplink_media/video_keyframes.rs"
));
const QUEUE_METADATA: &str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/client/src/app/uplink_media/uplink_queue_metadata.rs"
));

#[cfg(coverage)]
mod bundled_queue_runtime_knobs {
    use std::time::Duration;

    include!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/client/src/app/uplink_media/bundled_media_queue.rs"
    ));

    #[test]
    fn bundled_audio_video_span_uses_default_when_unset_or_invalid() {
        temp_env::with_var_unset("LESAVKA_BUNDLED_AUDIO_VIDEO_MAX_SPAN_MS", || {
            assert_eq!(
                bundled_audio_video_max_span(),
                Duration::from_millis(DEFAULT_BUNDLED_AUDIO_VIDEO_MAX_SPAN_MS)
            );
        });

        for value in ["", "0", "-1", "not-a-number"] {
            temp_env::with_var(
                "LESAVKA_BUNDLED_AUDIO_VIDEO_MAX_SPAN_MS",
                Some(value),
                || {
                    assert_eq!(
                        bundled_audio_video_max_span(),
                        Duration::from_millis(DEFAULT_BUNDLED_AUDIO_VIDEO_MAX_SPAN_MS)
                    );
                },
            );
        }
    }

    #[test]
    fn bundled_audio_video_span_accepts_positive_operator_override() {
        temp_env::with_var(
            "LESAVKA_BUNDLED_AUDIO_VIDEO_MAX_SPAN_MS",
            Some("125"),
            || {
                assert_eq!(bundled_audio_video_max_span(), Duration::from_millis(125));
            },
        );
    }
}

#[test]
fn bundled_component_keeps_audio_video_and_hevc_recovery_on_the_same_path() {
    for marker in [
        "const VIDEO_UPLINK_QUEUE",
        "const AUDIO_UPLINK_QUEUE",
        "const BUNDLED_MEDIA_UPLINK_QUEUE",
        "FreshQueuePolicy::LatestOnly",
        "FreshQueuePolicy::DrainOldest",
        "bundle_captured_media(",
    ] {
        assert!(
            BUNDLED_QUEUE.contains(marker),
            "bundled component should preserve marker {marker}"
        );
    }

    for marker in [
        "stream_webcam_media",
        "should_hold_hevc_bundle_for_keyframe_recovery",
        "note_hevc_capture_gap",
        "spawn_upstream_epoch_auto_heal",
        "microphone_telemetry.record_connected()",
    ] {
        assert!(
            WEBCAM_LOOP.contains(marker) || VIDEO_KEYFRAMES.contains(marker),
            "webcam component should preserve marker {marker}"
        );
    }

    for marker in [
        "capture_start_us",
        "capture_end_us",
        "attach_bundle_queue_metadata",
        "packet_audio_capture_pts_us",
        "packet_video_capture_pts_us",
    ] {
        assert!(
            QUEUE_METADATA.contains(marker),
            "bundle metadata should preserve marker {marker}"
        );
    }
}
