#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct DriverConfig {
    pub ring_entries: u32,
    pub fixed_buf_count: usize,
    pub fixed_buf_len: usize,
    pub fixed_file_slots: u32,
    pub provided_buf_entries: u16,
    pub provided_buf_len: usize,
    pub defer_taskrun: bool,

    pub cpu_id: Option<u16>,
}

impl Default for DriverConfig {
    fn default() -> Self {
        Self {
            ring_entries: 1024,
            fixed_buf_count: 64,
            fixed_buf_len: 4096,
            fixed_file_slots: 4096,
            provided_buf_entries: 128,
            provided_buf_len: 4096,
            defer_taskrun: false,
            cpu_id: None,
        }
    }
}

impl dope_core::driver::DriverConfig for DriverConfig {
    fn for_profile<P: dope_core::profile::Profile>() -> Self {
        Self {
            ring_entries: P::RING_ENTRIES,
            fixed_buf_count: 1024,
            fixed_buf_len: 4096,
            fixed_file_slots: 8192,
            provided_buf_entries: 4096,
            provided_buf_len: 4096,
            defer_taskrun: P::DEFER_TASKRUN,
            cpu_id: None,
        }
    }

    fn for_tcp_profile(ring_entries: u32, max_conn: usize, ingress_buf_cap: usize) -> Self {
        Self {
            ring_entries,
            fixed_buf_count: 64,
            fixed_buf_len: 4096,
            fixed_file_slots: max_conn.max(4096) as u32,
            provided_buf_entries: (max_conn.max(2048) * 4).min(32768) as u16,
            provided_buf_len: ingress_buf_cap,
            ..Self::default()
        }
    }

    fn for_quic_udp(provided_buf_entries: u32, provided_buf_len: u32) -> Self {
        Self {
            ring_entries: 256,
            fixed_buf_count: 0,
            fixed_buf_len: 0,
            fixed_file_slots: 16,
            provided_buf_entries: provided_buf_entries as u16,
            provided_buf_len: provided_buf_len as usize,
            ..Self::default()
        }
    }

    #[inline(always)]
    fn with_defer_taskrun(mut self, enable: bool) -> Self {
        self.defer_taskrun = enable;
        self
    }

    #[inline(always)]
    fn with_cpu_id(mut self, cpu: Option<u16>) -> Self {
        self.cpu_id = cpu;
        self
    }
}
