//这个文件的绝大部分内容是copy virtio_net.rs的，考虑到所有的驱动都要用操作系统提供的协议栈，我觉得可以把这些内容抽象出来

use crate::{
    arch::rand::rand,
    driver::{
        base::{
            class::Class,
            device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
        },
        net::{
            napi::NapiStruct, register_netdevice, types::InterfaceFlags, Iface, IfaceCommon,
            NetDeivceState, NetDeviceCommonData, Operstate,
        },
    },
    libs::{
        rwsem::{RwSemReadGuard, RwSemWriteGuard},
        spinlock::{SpinLock, SpinLockGuard},
    },
    net::generate_iface_id,
    process::namespace::net_namespace::INIT_NET_NAMESPACE,
    time::Instant,
};
use alloc::{
    string::{String, ToString},
    sync::{Arc, Weak},
};
use core::{
    fmt::Debug,
    sync::atomic::{AtomicBool, Ordering},
};
use log::info;
use smoltcp::{phy, wire::HardwareAddress};
use system_error::SystemError;

use super::e1000e::{E1000EBuffer, E1000EDevice};
use super::irq::e1000e_irq_manager;
use crate::driver::base::device::DeviceId;

const DEVICE_NAME: &str = "e1000e";

pub struct E1000ERxToken {
    buffer: Option<E1000EBuffer>,
    driver: E1000EDriver,
}
pub struct E1000ETxToken {
    driver: E1000EDriver,
    tx_reserved: bool,
}
pub struct E1000EDriver {
    pub inner: Arc<SpinLock<E1000EDevice>>,
    /// 指向所属网络接口的弱引用，用于 packet socket 分发
    iface: Arc<SpinLock<Weak<dyn Iface>>>,
    tx_reserved: Arc<AtomicBool>,
}
unsafe impl Send for E1000EDriver {}
unsafe impl Sync for E1000EDriver {}

impl Debug for E1000EDriver {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("E1000EDriver").finish_non_exhaustive()
    }
}

#[cast_to([sync] Iface)]
#[cast_to([sync] Device)]
#[derive(Debug)]
pub struct E1000EInterface {
    driver: E1000EDriver,
    common: IfaceCommon,
    inner: SpinLock<InnerE1000EInterface>,
    locked_kobj_state: LockedKObjectState,
}

#[derive(Debug)]
pub struct InnerE1000EInterface {
    netdevice_common: NetDeviceCommonData,
    device_common: DeviceCommonData,
    kobj_common: KObjectCommonData,
}

impl phy::RxToken for E1000ERxToken {
    fn consume<R, F>(mut self, f: F) -> R
    where
        F: FnOnce(&[u8]) -> R,
    {
        let buffer = self.buffer.take().unwrap();
        let packet = buffer.as_slice();

        // 向注册的 packet socket 分发数据包
        if let Some(iface) = self.driver.iface() {
            let pkt_type = crate::net::socket::packet::classify_packet(packet, &iface);
            crate::net::socket::packet::deliver_to_packet_sockets(&iface, packet, pkt_type);
        }

        let result = f(packet);
        buffer.free_buffer();
        return result;
    }
}

impl Drop for E1000ERxToken {
    fn drop(&mut self) {
        if let Some(buffer) = self.buffer.take() {
            buffer.free_buffer();
        }
    }
}

impl phy::TxToken for E1000ETxToken {
    fn consume<R, F>(mut self, len: usize, f: F) -> R
    where
        F: FnOnce(&mut [u8]) -> R,
    {
        let mut buffer = E1000EBuffer::new(len);
        let result = f(buffer.as_mut_slice());
        if !self.tx_reserved {
            if self.driver.try_raw_transmit(buffer.as_slice()).is_ok() {
                if let Some(iface) = self.driver.iface() {
                    crate::net::socket::packet::deliver_to_packet_sockets(
                        &iface,
                        buffer.as_slice(),
                        crate::net::socket::packet::PacketType::Outgoing,
                    );
                }
            }
            buffer.free_buffer();
            return result;
        }
        if let Some(iface) = self.driver.iface() {
            crate::net::socket::packet::deliver_to_packet_sockets(
                &iface,
                buffer.as_slice(),
                crate::net::socket::packet::PacketType::Outgoing,
            );
        }
        let mut device = self.driver.inner.lock();
        if let Err(buffer) = device.e1000e_transmit(buffer) {
            buffer.free_buffer();
        }
        drop(device);
        self.driver.release_tx();
        self.tx_reserved = false;
        return result;
    }
}

impl Drop for E1000ETxToken {
    fn drop(&mut self) {
        if self.tx_reserved {
            self.driver.release_tx();
            self.tx_reserved = false;
        }
    }
}

impl E1000EDriver {
    #[allow(clippy::arc_with_non_send_sync)]
    pub fn new(device: E1000EDevice) -> Self {
        let inner: Arc<SpinLock<E1000EDevice>> = Arc::new(SpinLock::new(device));
        let result = E1000EDriver {
            inner,
            iface: Arc::new(SpinLock::new(Weak::<E1000EInterface>::new())),
            tx_reserved: Arc::new(AtomicBool::new(false)),
        };
        return result;
    }

    /// 设置所属网络接口的引用
    pub fn set_iface(&self, iface: Weak<dyn Iface>) {
        *self.iface.lock() = iface;
    }

    /// 获取所属网络接口
    pub fn iface(&self) -> Option<Arc<dyn Iface>> {
        self.iface.lock().upgrade()
    }

    fn try_reserve_tx(&self) -> bool {
        self.tx_reserved
            .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
            .is_ok()
    }

    fn release_tx(&self) {
        self.tx_reserved.store(false, Ordering::Release);
    }

    /// Atomically checks descriptor availability and publishes one raw frame.
    /// The submitted DMA buffer remains owned by the TX ring until DD is
    /// observed when that descriptor is reused.
    pub fn try_raw_transmit(&self, frame: &[u8]) -> Result<(), SystemError> {
        const MAX_FRAME_LEN: usize = 1536;
        if frame.len() > MAX_FRAME_LEN || frame.len() > u16::MAX as usize {
            return Err(SystemError::EMSGSIZE);
        }

        if !self.try_reserve_tx() {
            return Err(SystemError::ENOBUFS);
        }
        let mut device = self.inner.lock();
        if !device.e1000e_can_transmit() {
            self.release_tx();
            return Err(SystemError::ENOBUFS);
        }

        let mut buffer = E1000EBuffer::new(frame.len());
        buffer.as_mut_slice().copy_from_slice(frame);
        let result = match device.e1000e_transmit(buffer) {
            Ok(()) => Ok(()),
            Err(buffer) => {
                buffer.free_buffer();
                Err(SystemError::ENOBUFS)
            }
        };
        drop(device);
        self.release_tx();
        result
    }
}

impl Clone for E1000EDriver {
    fn clone(&self) -> Self {
        return E1000EDriver {
            inner: self.inner.clone(),
            iface: self.iface.clone(),
            tx_reserved: self.tx_reserved.clone(),
        };
    }
}

impl phy::Device for E1000EDriver {
    type RxToken<'a> = E1000ERxToken;
    type TxToken<'a> = E1000ETxToken;

    fn receive(
        &mut self,
        _timestamp: smoltcp::time::Instant,
    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
        match self.inner.lock().e1000e_receive() {
            Some(buffer) => Some((
                E1000ERxToken {
                    buffer: Some(buffer),
                    driver: self.clone(),
                },
                E1000ETxToken {
                    driver: self.clone(),
                    tx_reserved: false,
                },
            )),
            None => {
                return None;
            }
        }
    }

    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
        if !self.try_reserve_tx() {
            return None;
        }
        match self.inner.lock().e1000e_can_transmit() {
            true => Some(E1000ETxToken {
                driver: self.clone(),
                tx_reserved: true,
            }),
            false => {
                self.release_tx();
                None
            }
        }
    }

    fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
        let mut caps = smoltcp::phy::DeviceCapabilities::default();
        // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元，而不是IP层的MTU。
        // The maximum size of the received packet is limited by the 82574 hardware to 1536 bytes. Packets larger then 1536 bytes are silently discarded. Any packet smaller than 1536 bytes is processed by the 82574.
        // 82574l manual pp205
        caps.max_transmission_unit = 1536;
        /*
           Maximum burst size, in terms of MTU.
           The network device is unable to send or receive bursts large than the value returned by this function.
           If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated.
        */
        caps.max_burst_size = Some(1);
        return caps;
    }
}

impl E1000EInterface {
    pub fn new(mut driver: E1000EDriver) -> Arc<Self> {
        use smoltcp::phy::Device;

        let iface_id = generate_iface_id();
        let mut iface_config = smoltcp::iface::Config::new(HardwareAddress::Ethernet(
            smoltcp::wire::EthernetAddress(driver.inner.lock().mac_address()),
        ));
        iface_config.random_seed = rand() as u64;

        let iface =
            smoltcp::iface::Interface::new(iface_config, &mut driver, Instant::now().into());

        let flags = InterfaceFlags::UP
            | InterfaceFlags::BROADCAST
            | InterfaceFlags::RUNNING
            | InterfaceFlags::MULTICAST
            | InterfaceFlags::LOWER_UP;
        let name = format!("eth{}", iface_id);
        let mtu = driver.capabilities().max_transmission_unit;

        let iface = Arc::new(E1000EInterface {
            driver,
            common: IfaceCommon::new(
                iface_id,
                crate::driver::net::types::InterfaceType::ETHER,
                name,
                mtu,
                flags,
                iface,
            ),
            inner: SpinLock::new(InnerE1000EInterface {
                netdevice_common: NetDeviceCommonData::default(),
                device_common: DeviceCommonData::default(),
                kobj_common: KObjectCommonData::default(),
            }),
            locked_kobj_state: LockedKObjectState::default(),
        });

        // 设置 NAPI：让收包处理走 bounded poll（对齐 Linux NAPI/ksoftirqd）。
        let napi_struct = NapiStruct::new(iface.clone(), 10);
        *iface.common.napi_struct.write() = Some(napi_struct);

        // 设置 driver 对接口的弱引用，用于 packet socket 分发
        iface
            .driver
            .set_iface(Arc::downgrade(&iface) as Weak<dyn Iface>);

        iface
    }

    pub fn inner(&self) -> SpinLockGuard<'_, InnerE1000EInterface> {
        return self.inner.lock();
    }
}

impl Device for E1000EInterface {
    fn dev_type(&self) -> DeviceType {
        DeviceType::Net
    }

    fn id_table(&self) -> IdTable {
        IdTable::new(DEVICE_NAME.to_string(), None)
    }

    fn bus(&self) -> Option<Weak<dyn Bus>> {
        self.inner().device_common.bus.clone()
    }

    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
        self.inner().device_common.bus = bus;
    }

    fn class(&self) -> Option<Arc<dyn Class>> {
        let mut guard = self.inner();
        let r = guard.device_common.class.clone()?.upgrade();
        if r.is_none() {
            guard.device_common.class = None;
        }

        return r;
    }

    fn set_class(&self, class: Option<Weak<dyn Class>>) {
        self.inner().device_common.class = class;
    }

    fn driver(&self) -> Option<Arc<dyn Driver>> {
        let r = self.inner().device_common.driver.clone()?.upgrade();
        if r.is_none() {
            self.inner().device_common.driver = None;
        }

        return r;
    }

    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
        self.inner().device_common.driver = driver;
    }

    fn is_dead(&self) -> bool {
        false
    }

    fn can_match(&self) -> bool {
        self.inner().device_common.can_match
    }

    fn set_can_match(&self, can_match: bool) {
        self.inner().device_common.can_match = can_match;
    }

    fn state_synced(&self) -> bool {
        true
    }

    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
        self.inner().device_common.get_parent_weak_or_clear()
    }

    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
        self.inner().device_common.parent = parent;
    }
}

impl Iface for E1000EInterface {
    fn common(&self) -> &IfaceCommon {
        return &self.common;
    }

    fn mac(&self) -> smoltcp::wire::EthernetAddress {
        let mac = self.driver.inner.lock().mac_address();
        return smoltcp::wire::EthernetAddress::from_bytes(&mac);
    }

    #[inline]
    fn iface_name(&self) -> String {
        return self.common.name();
    }

    fn poll(&self) -> bool {
        let mut driver = self.driver.clone();
        self.common.poll(&mut driver)
    }

    fn poll_napi(&self, budget: usize) -> crate::driver::net::napi::NapiPollResult {
        let mut driver = self.driver.clone();
        self.common.poll_napi(&mut driver, budget)
    }

    fn raw_transmit(&self, frame: &[u8]) -> Result<(), SystemError> {
        self.driver.try_raw_transmit(frame)?;
        if let Some(iface) = self.driver.iface() {
            crate::net::socket::packet::deliver_to_packet_sockets(
                &iface,
                frame,
                crate::net::socket::packet::PacketType::Outgoing,
            );
        }
        Ok(())
    }

    fn addr_assign_type(&self) -> u8 {
        return self.inner().netdevice_common.addr_assign_type;
    }

    fn net_device_type(&self) -> u16 {
        self.inner().netdevice_common.net_device_type = 1; // 以太网设备
        return self.inner().netdevice_common.net_device_type;
    }

    fn net_state(&self) -> NetDeivceState {
        return self.inner().netdevice_common.state;
    }

    fn set_net_state(&self, state: NetDeivceState) {
        self.inner().netdevice_common.state |= state;
    }

    fn clear_net_state(&self, state: NetDeivceState) {
        self.inner().netdevice_common.state &= !state;
    }

    fn operstate(&self) -> Operstate {
        return self.inner().netdevice_common.operstate;
    }

    fn set_operstate(&self, state: Operstate) {
        self.inner().netdevice_common.operstate = state;
    }

    fn mtu(&self) -> usize {
        self.common.mtu()
    }
}

impl KObject for E1000EInterface {
    fn as_any_ref(&self) -> &dyn core::any::Any {
        self
    }

    fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
        self.inner().kobj_common.kern_inode = inode;
    }

    fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
        self.inner().kobj_common.kern_inode.clone()
    }

    fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
        self.inner().kobj_common.parent.clone()
    }

    fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
        self.inner().kobj_common.parent = parent;
    }

    fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
        self.inner().kobj_common.kset.clone()
    }

    fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
        self.inner().kobj_common.kset = kset;
    }

    fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
        self.inner().kobj_common.kobj_type
    }

    fn name(&self) -> String {
        self.common.name()
    }

    fn set_name(&self, name: String) {
        self.common.set_name(name);
    }

    fn kobj_state(&self) -> RwSemReadGuard<'_, KObjectState> {
        self.locked_kobj_state.read()
    }

    fn kobj_state_mut(&self) -> RwSemWriteGuard<'_, KObjectState> {
        self.locked_kobj_state.write()
    }

    fn set_kobj_state(&self, state: KObjectState) {
        *self.locked_kobj_state.write() = state;
    }

    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
        self.inner().kobj_common.kobj_type = ktype;
    }
}

pub fn e1000e_driver_init(device: E1000EDevice, dev_id: Arc<DeviceId>) {
    let mac = smoltcp::wire::EthernetAddress::from_bytes(&device.mac_address());
    let driver = E1000EDriver::new(device);
    let iface = E1000EInterface::new(driver);
    // 标识网络设备已经启动
    iface.set_net_state(NetDeivceState::__LINK_STATE_START);

    // 将网卡的接口信息注册到全局的网卡接口信息表中
    // NET_DEVICES
    //     .write_irqsave()
    //     .insert(iface.nic_id(), iface.clone());
    INIT_NET_NAMESPACE.add_device(iface.clone());
    iface.common.set_net_namespace(INIT_NET_NAMESPACE.clone());

    info!("e1000e driver init successfully!\tMAC: [{}]", mac);

    register_netdevice(iface.clone()).expect("register lo device failed");

    // 注册 IRQ -> NAPI 映射：使 e1000e IRQ handler 在 hardirq 内直接 napi_schedule，
    // 避免唤醒 netns 线程扫描 device_list（对齐 Linux NAPI 语义）。
    if let Some(napi) = iface.napi_struct() {
        e1000e_irq_manager()
            .register_napi(dev_id, napi)
            .expect("register e1000e napi irq mapping failed");
    } else {
        log::warn!("e1000e iface has no napi_struct; irq mapping not registered");
    }
}
