use anyhow::{Context, Result};
#[cfg(coverage)]
use std::env;
#[cfg(coverage)]
use std::fs::OpenOptions;
#[cfg(coverage)]
use std::os::unix::fs::{FileTypeExt, OpenOptionsExt};

#[cfg(coverage)]
const STREAM_CTRL_SIZE_11: usize = 26;
#[cfg(coverage)]
const STREAM_CTRL_SIZE_15: usize = 34;
#[cfg(coverage)]
const STREAM_CTRL_SIZE_MAX: usize = STREAM_CTRL_SIZE_15;
#[cfg(coverage)]
const UVC_DATA_SIZE: usize = 60;

#[cfg(coverage)]
const UVC_STRING_CONTROL_IDX: u8 = 0;
#[cfg(coverage)]
const UVC_STRING_STREAMING_IDX: u8 = 1;

#[cfg(coverage)]
const USB_DIR_IN: u8 = 0x80;

#[cfg(coverage)]
const UVC_SET_CUR: u8 = 0x01;
#[cfg(coverage)]
const UVC_GET_CUR: u8 = 0x81;
#[cfg(coverage)]
const UVC_GET_MIN: u8 = 0x82;
#[cfg(coverage)]
const UVC_GET_MAX: u8 = 0x83;
#[cfg(coverage)]
const UVC_GET_RES: u8 = 0x84;
#[cfg(coverage)]
const UVC_GET_LEN: u8 = 0x85;
#[cfg(coverage)]
const UVC_GET_INFO: u8 = 0x86;
#[cfg(coverage)]
const UVC_GET_DEF: u8 = 0x87;

#[cfg(coverage)]
const UVC_VS_PROBE_CONTROL: u8 = 0x01;
#[cfg(coverage)]
const UVC_VS_COMMIT_CONTROL: u8 = 0x02;
#[cfg(coverage)]
const UVC_VC_REQUEST_ERROR_CODE_CONTROL: u8 = 0x02;

#[cfg(coverage)]
#[repr(C)]
#[derive(Clone, Copy)]
struct V4l2Event {
    _bytes: [u8; 64],
}

#[cfg(coverage)]
#[repr(C)]
#[derive(Clone, Copy)]
struct UsbCtrlRequest {
    b_request_type: u8,
    b_request: u8,
    w_value: u16,
    w_index: u16,
    w_length: u16,
}

#[cfg(coverage)]
#[repr(C)]
#[derive(Clone, Copy)]
struct UvcRequestData {
    length: i32,
    data: [u8; UVC_DATA_SIZE],
}

#[cfg(coverage)]
#[derive(Clone, Copy)]
struct UvcConfig {
    width: u32,
    height: u32,
    fps: u32,
    interval: u32,
    max_packet: u32,
    frame_size: u32,
}

#[cfg(coverage)]
struct PayloadCap {
    limit: u32,
    pct: u32,
    source: &'static str,
    periodic_dw: Option<u32>,
    non_periodic_dw: Option<u32>,
}

#[cfg(coverage)]
struct UvcState {
    cfg: UvcConfig,
    ctrl_len: usize,
    default: [u8; STREAM_CTRL_SIZE_MAX],
    probe: [u8; STREAM_CTRL_SIZE_MAX],
    commit: [u8; STREAM_CTRL_SIZE_MAX],
    cfg_snapshot: Option<ConfigfsSnapshot>,
}

#[cfg(coverage)]
#[derive(Clone, Copy)]
struct PendingRequest {
    interface: u8,
    selector: u8,
    expected_len: usize,
}

#[cfg(coverage)]
#[derive(Clone, Copy)]
struct UvcInterfaces {
    control: u8,
    streaming: u8,
}

#[cfg(coverage)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct ConfigfsSnapshot {
    width: u32,
    height: u32,
    default_interval: u32,
    frame_interval: u32,
    maxpacket: u32,
    maxburst: u32,
}
