// Simulated delayed/duplicate input packet contracts.
//
// Scope: verify the server HID stream remains bounded and freshness-biased
// under packet pressure, without opening real HID devices.
// Targets: `server/src/main/relay_service/input_stream_rpc.rs` and
// `server/src/runtime_support/hid_write.rs`.
// Why: the input path should not build an unbounded backlog that turns a
// delayed packet into a stale click or keystroke seconds later.

const INPUT_STREAM_RPC: &str =
    include_str!("../../../server/src/main/relay_service/input_stream_rpc.rs");
const HID_WRITE: &str = include_str!("../../../server/src/runtime_support/hid_write.rs");

#[test]
fn keyboard_stream_uses_small_ack_channel_and_bounded_report_delay() {
    assert!(
        INPUT_STREAM_RPC.contains("tokio::sync::mpsc::channel(32)"),
        "keyboard stream should keep the echo/ack queue small"
    );
    assert!(
        INPUT_STREAM_RPC.contains("let report_delay = live_keyboard_report_delay();"),
        "keyboard stream should preserve the configured live report pacing"
    );
}

#[test]
fn hid_write_retries_backpressure_but_does_not_retry_forever() {
    assert!(HID_WRITE.contains("LESAVKA_HID_WRITE_RETRIES"));
    assert!(HID_WRITE.contains(".unwrap_or(24)"));
    assert!(HID_WRITE.contains(".max(1)"));
    assert!(
        HID_WRITE.contains(
            "Err(last_error.unwrap_or_else(|| std::io::Error::from_raw_os_error(libc::EAGAIN)))"
        ),
        "bounded retry exhaustion should surface EAGAIN instead of hanging"
    );
}

#[test]
fn eagain_is_dropped_in_the_stream_instead_of_triggering_gadget_recovery() {
    assert!(
        INPUT_STREAM_RPC.contains("if e.raw_os_error() == Some(libc::EAGAIN)")
            && INPUT_STREAM_RPC.contains("write would block (dropped)"),
        "stale HID backpressure should drop the packet, not wedge recovery"
    );
}
