use crate::arch::rand::rand;
use crate::driver::base::class::Class;
use crate::driver::base::device::bus::Bus;
use crate::driver::base::device::driver::Driver;
use crate::driver::base::device::{Device, DeviceCommonData, DeviceType, IdTable};
use crate::driver::base::kobject::{
    KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState,
};
use crate::driver::base::kset::KSet;
use crate::driver::net::types::InterfaceFlags;
use crate::driver::net::{napi::napi_schedule, napi::NapiStruct};
use crate::filesystem::kernfs::KernFSInode;
use crate::init::initcall::INITCALL_DEVICE;
use crate::libs::rwsem::{RwSemReadGuard, RwSemWriteGuard};
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use crate::net::LOOPBACK_IFINDEX;
use crate::process::namespace::net_namespace::INIT_NET_NAMESPACE;
use crate::time::Instant;
use alloc::collections::VecDeque;
use alloc::fmt::Debug;
use alloc::string::{String, ToString};
use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use smoltcp::wire::HardwareAddress;
use smoltcp::{
    phy::{self},
    wire::{IpAddress, IpCidr},
};
use system_error::SystemError;
use unified_init::macros::unified_init;

use crate::libs::once::Once;

use super::{register_netdevice, NetDeivceState, NetDeviceCommonData, Operstate};

use super::{Iface, IfaceCommon};

const DEVICE_NAME: &str = "loopback";

/// ## 环回接收令牌
/// 用于储存lo网卡接收到的数据
pub struct LoopbackRxToken {
    buffer: Vec<u8>,
    driver: LoopbackDriver,
}

impl phy::RxToken for LoopbackRxToken {
    /// ## 实现Rxtoken的consume函数
    /// 接受一个函数 `f`，并在 `self.buffer` 上调用它。
    ///
    /// ## 参数
    /// - mut self ：一个可变的 `LoopbackRxToken` 实例。
    /// - f ：接受一个可变的 u8 切片，并返回类型 `R` 的结果。
    ///
    /// ## 返回值
    /// 返回函数 `f` 在 `self.buffer` 上的调用结果。
    fn consume<R, F>(self, f: F) -> R
    where
        F: FnOnce(&[u8]) -> R,
    {
        if let Some(iface) = self.driver.iface() {
            crate::net::socket::packet::deliver_ip_to_packet_sockets(
                &iface,
                &self.buffer,
                crate::net::socket::packet::PacketType::Loopback,
            );
        }
        f(self.buffer.as_slice())
    }
}

/// ## 环回发送令牌
/// 返回驱动用于操作lo设备
pub struct LoopbackTxToken {
    driver: LoopbackDriver,
}

impl phy::TxToken for LoopbackTxToken {
    /// ## 实现TxToken的consume函数
    /// 向lo的队列推入待发送的数据报，实现环回
    ///
    /// ## 参数
    /// - self
    /// - len：数据包的长度
    /// - f：接受一个可变的 u8 切片，并返回类型 `R` 的结果。
    ///
    /// ## 返回值
    /// 返回f对数据包操纵的结果
    fn consume<R, F>(self, len: usize, f: F) -> R
    where
        F: FnOnce(&mut [u8]) -> R,
    {
        let mut buffer = vec![0; len];
        let result = f(buffer.as_mut_slice());
        if let Some(iface) = self.driver.iface() {
            crate::net::socket::packet::deliver_ip_to_packet_sockets(
                &iface,
                &buffer,
                crate::net::socket::packet::PacketType::Outgoing,
            );
        }
        let _ = self.driver.submit_frame(buffer);
        // debug!("lo transmit!");
        result
    }
}

#[derive(Default)]
/// ## Loopback设备
/// 成员是一个队列，用来存放接受到的数据包。
/// 当使用lo发送数据包时，不会把数据包传到link层，而是直接发送到该队列，实现环回。
pub struct Loopback {
    //回环设备的缓冲区,接受的数据包会存放在这里，发送的数据包也会发送到这里，实现环回
    queue: VecDeque<Vec<u8>>,
}

impl Loopback {
    /// ## Loopback处理接受到的数据包函数
    /// Loopback接受到数据后会调用这个函数来弹出接收的数据，返回给协议栈
    ///
    /// ## 参数
    /// - &mut self ：自身可变引用
    ///
    /// ## 返回值
    /// - queue的头部数据包
    pub fn loopback_receive(&mut self) -> Vec<u8> {
        let buffer = self.queue.pop_front();
        match buffer {
            Some(buffer) => {
                // log::debug!(
                //     "lo receive: {} bytes, remaining_queue_len={}, self_ptr={:p}",
                //     buffer.len(),
                //     self.queue.len(),
                //     self
                // );
                return buffer;
            }
            None => {
                if !self.queue.is_empty() {
                    log::warn!("lo receive: queue not empty but pop_front returned None!");
                }
                return Vec::new();
            }
        }
    }
    /// ## Loopback发送数据包的函数
    /// Loopback发送数据包给自己的接收队列，实现环回
    ///
    /// ## 参数
    /// - &mut self：自身可变引用
    /// - buffer：需要发送的数据包
    pub fn loopback_transmit(&mut self, buffer: Vec<u8>) {
        // log::debug!(
        //     "lo transmit: {} bytes, queue_len={}, self_ptr={:p}",
        //     buffer.len(),
        //     self.queue.len(),
        //     self
        // );
        self.queue.push_back(buffer);
    }
}

/// ## Loopback驱动
/// 负责操作Loopback设备实现基本的网卡功能
#[derive(Clone)]
pub struct LoopbackDriver {
    pub inner: Arc<SpinLock<Loopback>>,
    /// 指向所属网络接口的弱引用，用于唤醒 netns 轮询线程
    iface: Arc<SpinLock<Option<Weak<dyn Iface>>>>,
}

impl Default for LoopbackDriver {
    /// ## LoopbackDriver创建函数
    fn default() -> Self {
        let inner = Arc::new(SpinLock::new(Loopback::default()));
        LoopbackDriver {
            inner,
            iface: Arc::new(SpinLock::new(None)),
        }
    }
}

impl phy::Device for LoopbackDriver {
    type RxToken<'a>
        = LoopbackRxToken
    where
        Self: 'a;
    type TxToken<'a>
        = LoopbackTxToken
    where
        Self: 'a;
    /// ## 返回设备的物理层特性。
    /// lo设备的最大传输单元为65535，最大突发大小为1，传输介质默认为Ethernet
    fn capabilities(&self) -> phy::DeviceCapabilities {
        let mut result = phy::DeviceCapabilities::default();
        result.max_transmission_unit = 65535;
        result.max_burst_size = Some(1);
        result.medium = smoltcp::phy::Medium::Ip;
        return result;
    }
    /// ## Loopback驱动处理接受数据事件
    /// 驱动调用Loopback的receive函数，处理buffer封装成（rx，tx）返回给上层
    ///
    /// ## 参数
    /// - `&mut self` ：自身可变引用
    /// - `_timestamp`
    ///
    /// ## 返回值
    /// - None: 如果接收队列为空，返回 `None`，以通知上层没有可以接收的包
    /// - Option::Some((rx, tx))：如果接收队列不为空，返回 `Some`，其中包含一个接收令牌 `rx` 和一个发送令牌 `tx`
    fn receive(
        &mut self,
        _timestamp: smoltcp::time::Instant,
    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
        loop {
            let buffer = self.inner.lock().loopback_receive();
            // receive 队列为空，返回 None 以通知上层没有可以 receive 的包
            if buffer.is_empty() {
                return None;
            }

            if let Some(iface) = self.iface() {
                if iface.should_drop_rx_packet(&buffer) {
                    // Drop this packet and try the next one in the queue.
                    continue;
                }
            }

            let rx = LoopbackRxToken {
                buffer,
                driver: self.clone(),
            };
            let tx = LoopbackTxToken {
                driver: self.clone(),
            };
            return Some((rx, tx));
        }
    }
    /// ## Loopback驱动处理发送数据包事件
    /// Loopback驱动在需要发送数据时会调用这个函数来获取一个发送令牌。
    ///
    /// ## 参数
    /// - `&mut self` ：自身可变引用
    /// - `_timestamp`
    ///
    /// ## 返回值
    /// - 返回一个 `Some`，其中包含一个发送令牌，该令牌包含一个对自身的克隆引用
    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
        Some(LoopbackTxToken {
            driver: self.clone(),
        })
    }
}

impl LoopbackDriver {
    const MAX_PACKET_LEN: usize = 65535;

    pub fn set_iface(&self, iface: Weak<dyn Iface>) {
        *self.iface.lock() = Some(iface);
    }

    pub fn iface(&self) -> Option<Arc<dyn Iface>> {
        self.iface.lock().as_ref().and_then(|w| w.upgrade())
    }

    pub fn has_pending_rx(&self) -> bool {
        !self.inner.lock().queue.is_empty()
    }

    fn submit_frame(&self, frame: Vec<u8>) -> Result<(), SystemError> {
        if frame.len() > Self::MAX_PACKET_LEN {
            return Err(SystemError::EMSGSIZE);
        }
        self.inner.lock().loopback_transmit(frame);
        if let Some(iface) = self.iface() {
            if let Some(napi) = iface.napi_struct() {
                napi_schedule(napi);
            } else if let Some(netns) = iface.common().net_namespace() {
                netns.wakeup_poll_thread();
            }
        }
        Ok(())
    }

    pub fn try_raw_transmit(&self, frame: &[u8]) -> Result<(), SystemError> {
        if frame.len() > Self::MAX_PACKET_LEN {
            return Err(SystemError::EMSGSIZE);
        }
        self.submit_frame(frame.to_vec())
    }
}

/// ## LoopbackInterface结构
/// 封装驱动包裹器和iface，设置接口名称
#[cast_to([sync] Iface)]
#[cast_to([sync] Device)]
pub struct LoopbackInterface {
    driver: LoopbackDriver,
    common: IfaceCommon,
    inner: SpinLock<InnerLoopbackInterface>,
    locked_kobj_state: LockedKObjectState,
}

pub struct InnerLoopbackInterface {
    netdevice_common: NetDeviceCommonData,
    device_common: DeviceCommonData,
    kobj_common: KObjectCommonData,
}

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

impl LoopbackInterface {
    pub const DEVICE_NAME: &str = "lo";

    /// ## `new` 是一个公共函数，用于创建一个新的 `LoopbackInterface` 实例。
    /// 使用 Linux 约定的 loopback 接口 ID。创建一个新的接口配置，设置其硬件地址和随机种子，使用接口配置和驱动器创建一个新的 `smoltcp::iface::Interface` 实例。
    /// 设置接口的 IP 地址为 127.0.0.1。
    /// Saves a cloneable driver handle; the underlying queue and the interface
    /// back-reference are protected by a shared lock.
    /// 创建一个新的 `LoopbackInterface` 实例，包含驱动器、接口 ID、接口和名称，并将其封装在一个 `Arc` 中。
    /// ## 参数
    /// - `driver`：一个 `LoopbackDriver` 实例，用于驱动网络环回操作。
    ///
    /// ## 返回值
    /// 返回一个 `Arc<Self>`，即一个指向新创建的 `LoopbackInterface` 实例的智能指针。
    pub fn new(driver: LoopbackDriver) -> Arc<Self> {
        Self::new_with_ifindex(driver, LOOPBACK_IFINDEX)
    }

    /// 在指定网络命名空间中创建 loopback，使用给定的 per-netns ifindex（Linux 新 netns 中 lo 通常为 1）。
    pub fn new_with_ifindex(mut driver: LoopbackDriver, ifindex: usize) -> Arc<Self> {
        use smoltcp::phy::Device;

        let iface_id = ifindex;

        // let hardware_addr = HardwareAddress::Ethernet(smoltcp::wire::EthernetAddress([
        //     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // ]));

        let hardware_addr = HardwareAddress::Ip;

        let mut iface_config = smoltcp::iface::Config::new(hardware_addr);

        iface_config.random_seed = rand() as u64;

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

        iface.set_any_ip(true);

        let addr = IpAddress::v4(127, 0, 0, 1);
        let cidr = IpCidr::new(addr, 8);

        // IPv6 loopback address ::1/128 (Linux 默认在 lo 上配置)。
        let addr6 = IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1);
        let cidr6 = IpCidr::new(addr6, 128);

        //设置网卡地址为127.0.0.1
        iface.update_ip_addrs(|ip_addrs| {
            ip_addrs.push(cidr).expect("Push ipCidr failed: full");
            ip_addrs.push(cidr6).expect("Push ipCidr failed: full");
        });

        iface.routes_mut().update(|routes_map| {
            routes_map
                .push(smoltcp::iface::Route {
                    cidr,
                    via_router: None,
                    preferred_until: None,
                    expires_at: None,
                })
                .expect("Add default ipv4 route failed: full");

            routes_map
                .push(smoltcp::iface::Route {
                    cidr: cidr6,
                    via_router: None,
                    preferred_until: None,
                    expires_at: None,
                })
                .expect("Add default ipv6 route failed: full");
        });

        let flags = InterfaceFlags::LOOPBACK
            | InterfaceFlags::UP
            | InterfaceFlags::RUNNING
            | InterfaceFlags::LOWER_UP;
        let mtu = driver.capabilities().max_transmission_unit;

        let iface = Arc::new(LoopbackInterface {
            driver,
            common: IfaceCommon::new(
                iface_id,
                super::types::InterfaceType::LOOPBACK,
                Self::DEVICE_NAME.to_string(),
                mtu,
                flags,
                iface,
            ),
            inner: SpinLock::new(InnerLoopbackInterface {
                netdevice_common: NetDeviceCommonData::default(),
                device_common: DeviceCommonData::default(),
                kobj_common: KObjectCommonData::default(),
            }),
            locked_kobj_state: LockedKObjectState::default(),
        });

        // 记录 iface 弱引用，用于 lo 发送时唤醒 netns 轮询线程
        let iface_dyn = iface.clone() as Arc<dyn Iface>;
        iface.driver.set_iface(Arc::downgrade(&iface_dyn));

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

        iface
    }

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

//TODO: 向sysfs注册lo设备
impl KObject for LoopbackInterface {
    fn as_any_ref(&self) -> &dyn core::any::Any {
        self
    }

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

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

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

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

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

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

    fn kobj_type(&self) -> Option<&'static dyn 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;
    }
}

impl Device for LoopbackInterface {
    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 LoopbackInterface {
    fn common(&self) -> &IfaceCommon {
        &self.common
    }

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

    /// 由于lo网卡设备不是实际的物理设备，其mac地址需要手动设置为一个默认值，这里默认为00:00:00:00:00
    fn mac(&self) -> smoltcp::wire::EthernetAddress {
        let mac = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
        smoltcp::wire::EthernetAddress(mac)
    }

    fn poll(&self) -> bool {
        // loopback 特有语义：
        // 一次 `poll()` 的 egress 阶段可能会把新包重新塞回 lo 的本地接收队列。
        // 即使 smoltcp 没返回 `SocketStateChanged` / `poll_at == Now`，
        // 这些新包也需要立刻再 poll 一轮才能被当前线程吃掉。
        let mut driver = self.driver.clone();
        let progressed = self.common.poll(&mut driver);
        progressed || self.driver.has_pending_rx()
    }

    fn poll_napi(&self, budget: usize) -> super::napi::NapiPollResult {
        // 与普通 poll 相同：若 egress 刚把包送回 lo 队列，则 NAPI 也必须继续自驱动。
        let mut driver = self.driver.clone();
        let mut result = self.common.poll_napi(&mut driver, budget);
        result.poll_again |= self.driver.has_pending_rx();
        result
    }

    fn raw_transmit(&self, frame: &[u8]) -> Result<(), SystemError> {
        if frame.len() < 14 {
            return Err(SystemError::EINVAL);
        }
        self.driver.try_raw_transmit(&frame[14..])?;
        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 should_drop_rx_packet(&self, packet: &[u8]) -> bool {
        self.common.should_drop_rx_packet(packet)
    }

    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 = 24; // 环回设备
        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()
    }
}

pub fn generate_loopback_iface_default() -> Arc<LoopbackInterface> {
    let iface = LoopbackInterface::new(LoopbackDriver::default());
    // 标识网络设备已经启动
    iface.set_net_state(NetDeivceState::__LINK_STATE_START);

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

    iface
}

pub fn loopback_probe() {
    loopback_driver_init();
}

/// # lo网卡设备初始化函数
/// 创建驱动和iface，初始化一个lo网卡，添加到全局NET_DEVICES中
pub fn loopback_driver_init() {
    static INIT: Once = Once::new();
    INIT.call_once(|| {
        // If already initialized (e.g., by earlier init path), do nothing.
        if INIT_NET_NAMESPACE.loopback_iface().is_some() {
            return;
        }

        let iface = generate_loopback_iface_default();

        INIT_NET_NAMESPACE.add_device(iface.clone());
        INIT_NET_NAMESPACE.set_loopback_iface(iface.clone());
        iface.common.set_net_namespace(INIT_NET_NAMESPACE.clone());
    });
}

/// ## lo网卡设备的注册函数
#[unified_init(INITCALL_DEVICE)]
pub fn loopback_init() -> Result<(), SystemError> {
    loopback_probe();
    log::debug!("Successfully init loopback device");
    return Ok(());
}
