// Downstream video chaos contracts.
//
// Scope: source-stall, decoder-stall, and dropped-frame behavior without
// requiring capture cards or opening UI windows.
// Targets: server eye capture, server stream core, and client monitor pipelines.
// Why: when downstream video gets rough, it should drop or report stale frames
// rather than hiding backlog, wedging the stream, or silently showing black.

const SERVER_EYE_CAPTURE: &str = include_str!("../../../../server/src/video/eye_capture.rs");
const SERVER_STREAM_CORE: &str = include_str!("../../../../server/src/video/stream_core.rs");
const CLIENT_MONITOR: &str = include_str!("../../../../client/src/output/video/monitor_window.rs");
const CLIENT_UNIFIED_MONITOR: &str =
    include_str!("../../../../client/src/output/video/unified_monitor.rs");

#[test]
fn source_stalls_are_reported_on_the_stream_and_in_logs() {
    for marker in [
        "first_frame_timeout_ms",
        "tx_for_first_frame_watchdog",
        "Status::internal(detail)",
        "idle_ms",
        "stall_warn_ms",
    ] {
        assert!(
            SERVER_EYE_CAPTURE.contains(marker),
            "source stall handling should preserve marker {marker}"
        );
    }
}

#[test]
fn decoder_and_pipeline_errors_surface_instead_of_silently_blackholing() {
    for marker in [
        "pipeline error",
        "stream_errors.blocking_send(Err(Status::internal(detail)))",
        "pipeline warning",
    ] {
        assert!(
            SERVER_STREAM_CORE.contains(marker),
            "server pipeline errors should preserve marker {marker}"
        );
    }
    for source in [CLIENT_MONITOR, CLIENT_UNIFIED_MONITOR] {
        assert!(
            source.contains("gst") && source.contains("Error(e)") && source.contains("Warning(w)"),
            "client decoder pipeline should continue logging GStreamer errors and warnings"
        );
    }
}

#[test]
fn dropped_frames_increment_telemetry_and_force_decoder_recovery_on_idr() {
    for marker in [
        "dropped_window.fetch_add(1",
        "dropped_total_for_cb.fetch_add(1",
        "wait_for_idr.store(true",
        "if wait_for_idr.load(Ordering::Relaxed) && !is_idr",
        "if is_idr",
        "wait_for_idr.store(false",
    ] {
        assert!(
            SERVER_EYE_CAPTURE.contains(marker),
            "dropped-frame recovery should preserve marker {marker}"
        );
    }
}

#[test]
fn client_decoder_queues_drop_downstream_when_display_lags() {
    for source in [CLIENT_MONITOR, CLIENT_UNIFIED_MONITOR] {
        assert!(
            source.matches("leaky=downstream").count() >= 1,
            "client display path should drop stale frames under display lag"
        );
        assert!(
            source.contains("block=false"),
            "client display appsrc should not block network receive loops"
        );
    }
}
