use super::*;
use serial_test::serial;
use std::fs;
use temp_env::with_var;
use tempfile::NamedTempFile;

fn sample_cfg() -> UvcConfig {
    UvcConfig {
        width: 1280,
        height: 720,
        fps: 25,
        interval: 400_000,
        max_packet: 1024,
        frame_size: 1_843_200,
    }
}

fn sample_interfaces() -> UvcInterfaces {
    UvcInterfaces {
        control: UVC_STRING_CONTROL_IDX,
        streaming: UVC_STRING_STREAMING_IDX,
    }
}

#[test]
fn branch_smoke_covers_low_hit_paths() {
    let interfaces = sample_interfaces();
    let mut state = UvcState::new(sample_cfg());
    let mut pending = Some(PendingRequest {
        interface: interfaces.control,
        selector: UVC_VS_PROBE_CONTROL,
        expected_len: STREAM_CTRL_SIZE_11,
    });
    handle_data(
        -1,
        0,
        &mut state,
        &mut pending,
        interfaces,
        UvcRequestData {
            length: STREAM_CTRL_SIZE_11 as i32,
            data: [0u8; UVC_DATA_SIZE],
        },
        true,
    );
    assert!(pending.is_none());
    assert!(
        build_in_response(
            &state,
            interfaces,
            interfaces.streaming,
            0xFE,
            UVC_GET_CUR,
            8
        )
        .is_none()
    );
    let short = [0u8; 8];
    let _ = sanitize_streaming_control(&short, &state);
}

#[test]
fn io_helpers_cover_empty_and_missing_sources() {
    let empty = NamedTempFile::new().expect("tmp");
    fs::write(empty.path(), "\n").expect("write empty");
    assert_eq!(read_u32_first(empty.path().to_str().expect("path")), None);

    let missing = format!("/tmp/lesavka-uvc-missing-{}", std::process::id());
    assert_eq!(read_fifo_min(&missing), None);
}

#[test]
#[serial]
fn main_coverage_mode_returns_error_for_non_uvc_node() {
    with_var("LESAVKA_UVC_DEV", Some("/dev/null"), || {
        with_var("LESAVKA_UVC_BLOCKING", Some("1"), || {
            let result = main();
            assert!(result.is_err());
        });
    });
}
