use crate::{
    filesystem::epoll::{event_poll::EventPoll, EPollEventType},
    filesystem::vfs::iov::IoVecs,
    filesystem::vfs::{
        fasync::{FAsyncItems, FASYNC_POLL_IN},
        utils::DName,
        vcore::generate_inode_id,
        InodeId,
    },
    libs::mutex::Mutex,
    libs::rwsem::RwSem,
    libs::wait_queue::WaitQueue,
    net::{
        posix::MsgHdr,
        socket::{
            self,
            common::{
                parse_timeval_opt, write_i32_getsockopt, write_timeval_opt, write_u32_getsockopt,
                EPollItems,
            },
            endpoint::Endpoint,
            unix::{UnixEndpoint, UnixEndpointBound},
            AddressFamily, Socket, PMSG, PSOCK, PSOL,
        },
    },
};
use alloc::{
    collections::VecDeque,
    sync::{Arc, Weak},
    vec::Vec,
};
use core::sync::atomic::{AtomicBool, AtomicI32, AtomicU64, AtomicUsize, Ordering};
use hashbrown::HashMap;
use system_error::SystemError;

use crate::time::Duration;

use crate::process::namespace::net_namespace::NetNamespace;
use crate::{
    filesystem::vfs::file::File,
    net::socket::unix::{current_ucred, nobody_ucred, UCred},
    process::ProcessManager,
    syscall::user_access::UserBufferReader,
};

// Use common ancillary message types from parent module
use super::{cmsg_align, CmsgBuffer, Cmsghdr, MSG_CTRUNC, SCM_CREDENTIALS, SCM_RIGHTS, SOL_SOCKET};

/// Unix 域数据报消息
#[derive(Debug, Clone)]
struct DatagramMessage {
    /// 消息数据
    data: Vec<u8>,
    /// SCM_RIGHTS file list associated with this datagram.
    rights: Vec<Arc<File>>,

    /// SCM_CREDENTIALS associated with this datagram.
    ///
    /// Present when explicitly provided via sendmsg SCM_CREDENTIALS or when
    /// credentials were auto-attached at send time due to SO_PASSCRED.
    creds: Option<UCred>,
    /// 发送方地址
    sender_addr: Option<UnixEndpointBound>,
    /// 发送端 SO_SNDBUF 记账的长度
    sender_accounted_len: usize,
}

impl DatagramMessage {
    fn new(
        data: Vec<u8>,
        sender_addr: Option<UnixEndpointBound>,
        rights: Vec<Arc<File>>,
        creds: Option<UCred>,
    ) -> Self {
        let sender_accounted_len = data.len();
        Self {
            data,
            rights,
            creds,
            sender_addr,
            sender_accounted_len,
        }
    }
}

/// Unix 域数据报 Socket 的内部状态
#[derive(Debug)]
struct Inner {
    /// 本地绑定地址
    local_addr: Option<UnixEndpointBound>,
    /// 连接的对端地址（用于 connect 后的 send）
    peer_addr: Option<UnixEndpointBound>,
    /// 接收队列 - 保存接收到的数据报
    recv_queue: VecDeque<DatagramMessage>,
    /// 接收队列的最大容量（消息数量）
    recv_queue_capacity: usize,
}

impl Inner {
    const DEFAULT_RECV_QUEUE_CAPACITY: usize = 4096;

    fn new() -> Self {
        Self {
            local_addr: None,
            peer_addr: None,
            recv_queue: VecDeque::new(),
            recv_queue_capacity: Self::DEFAULT_RECV_QUEUE_CAPACITY,
        }
    }

    fn bind(
        &mut self,
        endpoint: UnixEndpoint,
        netns: &Arc<NetNamespace>,
    ) -> Result<(), SystemError> {
        if self.local_addr.is_some() {
            return endpoint.bind_unnamed();
        }
        let bound_addr = endpoint.bind_in(netns)?;
        self.local_addr = Some(bound_addr);
        Ok(())
    }

    fn connect(
        &mut self,
        endpoint: UnixEndpoint,
        netns: &Arc<NetNamespace>,
    ) -> Result<(), SystemError> {
        let peer_addr = endpoint.connect_in(netns)?;
        self.peer_addr = Some(peer_addr);
        Ok(())
    }

    fn local_endpoint(&self) -> Option<UnixEndpointBound> {
        self.local_addr.clone()
    }

    fn peer_endpoint(&self) -> Option<UnixEndpointBound> {
        self.peer_addr.clone()
    }

    fn push_message(&mut self, msg: DatagramMessage) -> Result<(), SystemError> {
        if self.recv_queue.len() >= self.recv_queue_capacity {
            return Err(SystemError::ENOBUFS);
        }
        self.recv_queue.push_back(msg);
        Ok(())
    }

    fn pop_message(&mut self) -> Option<DatagramMessage> {
        self.recv_queue.pop_front()
    }

    fn has_message(&self) -> bool {
        !self.recv_queue.is_empty()
    }
}

/// 抽象套接字的键：namespace ID + 抽象名称
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct AbstractSocketKey {
    nsid: usize,
    name: Arc<[u8]>,
}

impl AbstractSocketKey {
    fn new(nsid: usize, name: Arc<[u8]>) -> Self {
        Self { nsid, name }
    }
}

/// 抽象名称绑定的 socket 表
struct AbstractSocketTable {
    inner: RwSem<HashMap<AbstractSocketKey, Weak<UnixDatagramSocket>>>,
}

impl AbstractSocketTable {
    fn new() -> Self {
        Self {
            inner: RwSem::new(HashMap::new()),
        }
    }

    fn insert(&self, nsid: usize, name: Arc<[u8]>, socket: Weak<UnixDatagramSocket>) {
        self.inner
            .write()
            .insert(AbstractSocketKey::new(nsid, name), socket);
    }

    fn remove(&self, nsid: usize, name: Arc<[u8]>) -> Option<Weak<UnixDatagramSocket>> {
        self.inner
            .write()
            .remove(&AbstractSocketKey::new(nsid, name))
    }

    fn get(&self, nsid: usize, name: Arc<[u8]>) -> Option<Arc<UnixDatagramSocket>> {
        self.inner
            .read()
            .get(&AbstractSocketKey::new(nsid, name))
            .and_then(Weak::upgrade)
    }
}

/// Unix 域数据报 Socket 的绑定表
/// 用于根据地址查找对应的 socket
struct BindTable {
    /// 路径绑定的 socket
    path_sockets: RwSem<HashMap<DName, Weak<UnixDatagramSocket>>>,
    /// 抽象名称绑定的 socket
    abstract_sockets: AbstractSocketTable,
}

impl BindTable {
    fn new() -> Self {
        Self {
            path_sockets: RwSem::new(HashMap::new()),
            abstract_sockets: AbstractSocketTable::new(),
        }
    }

    fn register(&self, addr: &UnixEndpointBound, socket: &Arc<UnixDatagramSocket>) {
        match addr {
            UnixEndpointBound::Path(path) => {
                self.path_sockets
                    .write()
                    .insert(path.clone(), Arc::downgrade(socket));
            }
            UnixEndpointBound::Abstract(handle) => {
                self.abstract_sockets
                    .insert(handle.nsid(), handle.name(), Arc::downgrade(socket));
            }
        }
    }

    fn unregister(&self, addr: &UnixEndpointBound) {
        match addr {
            UnixEndpointBound::Path(path) => {
                self.path_sockets.write().remove(path);
            }
            UnixEndpointBound::Abstract(handle) => {
                self.abstract_sockets.remove(handle.nsid(), handle.name());
            }
        }
    }

    fn lookup(&self, addr: &UnixEndpointBound) -> Option<Arc<UnixDatagramSocket>> {
        match addr {
            UnixEndpointBound::Path(path) => {
                self.path_sockets.read().get(path).and_then(Weak::upgrade)
            }
            UnixEndpointBound::Abstract(handle) => {
                self.abstract_sockets.get(handle.nsid(), handle.name())
            }
        }
    }
}

lazy_static! {
    static ref BIND_TABLE: BindTable = BindTable::new();
}

/// Unix 域数据报 Socket
///
/// 实现无连接的、可靠的、保持消息边界的数据报传输。
/// 与 UDP 不同，Unix 域数据报在本地是可靠的（不会丢包）。
#[derive(Debug)]
#[cast_to([sync] Socket)]
pub struct UnixDatagramSocket {
    inner: Mutex<Inner>,
    epitems: EPollItems,
    fasync_items: FAsyncItems,
    wait_queue: Arc<WaitQueue>,
    inode_id: InodeId,
    open_files: AtomicUsize,
    fsnotify_watches: AtomicUsize,
    netns: Arc<NetNamespace>,
    is_nonblocking: AtomicBool,
    sndbuf: AtomicUsize,
    snd_used: AtomicUsize,
    rcvbuf: AtomicUsize,
    rcvlowat: AtomicI32,
    send_timeout_us: AtomicU64,
    recv_timeout_us: AtomicU64,
    self_weak: Weak<UnixDatagramSocket>,

    passcred: AtomicBool,

    is_read_shutdown: AtomicBool,
    is_write_shutdown: AtomicBool,
}

impl UnixDatagramSocket {
    /// 默认的缓冲区大小
    pub const DEFAULT_BUF_SIZE: usize = 64 * 1024;
    pub const MIN_SOCKET_BUF_SIZE: usize = 1024;
    /// 单个消息的最大大小
    // Linux unix-dgram does not impose a tiny 64KiB limit; large datagrams are allowed
    // and failures are generally reported as ENOBUFS when memory/socket buffers are insufficient.
    // gVisor tests require at least 4MiB.
    pub const MAX_MSG_SIZE: usize = 16 * 1024 * 1024;

    pub fn new(is_nonblocking: bool) -> Arc<Self> {
        let netns = ProcessManager::current_netns();
        Arc::new_cyclic(|weak| Self {
            inner: Mutex::new(Inner::new()),
            epitems: EPollItems::default(),
            fasync_items: FAsyncItems::default(),
            wait_queue: Arc::new(WaitQueue::default()),
            inode_id: generate_inode_id(),
            open_files: AtomicUsize::new(0),
            fsnotify_watches: AtomicUsize::new(0),
            netns: netns.clone(),
            is_nonblocking: AtomicBool::new(is_nonblocking),
            sndbuf: AtomicUsize::new(Self::DEFAULT_BUF_SIZE),
            snd_used: AtomicUsize::new(0),
            rcvbuf: AtomicUsize::new(Self::DEFAULT_BUF_SIZE),
            rcvlowat: AtomicI32::new(1),
            send_timeout_us: AtomicU64::new(u64::MAX),
            recv_timeout_us: AtomicU64::new(u64::MAX),
            self_weak: weak.clone(),

            passcred: AtomicBool::new(false),

            is_read_shutdown: AtomicBool::new(false),
            is_write_shutdown: AtomicBool::new(false),
        })
    }

    /// 创建一对已连接的 Unix 数据报 socket
    pub fn new_pair(is_nonblocking: bool) -> (Arc<Self>, Arc<Self>) {
        let socket_a = Self::new(is_nonblocking);
        let socket_b = Self::new(is_nonblocking);

        let netns = socket_a.netns.clone();

        // 为每个 socket 分配一个临时的抽象地址
        let addr_a = netns
            .unix_abstract_table()
            .alloc_ephemeral_abstract_name()
            .ok();
        let addr_b = netns
            .unix_abstract_table()
            .alloc_ephemeral_abstract_name()
            .ok();

        // 设置本地和对端地址
        {
            let mut inner_a = socket_a.inner.lock();
            inner_a.local_addr = addr_a.clone().map(UnixEndpointBound::Abstract);
            inner_a.peer_addr = addr_b.clone().map(UnixEndpointBound::Abstract);
        }
        {
            let mut inner_b = socket_b.inner.lock();
            inner_b.local_addr = addr_b.clone().map(UnixEndpointBound::Abstract);
            inner_b.peer_addr = addr_a.clone().map(UnixEndpointBound::Abstract);
        }

        // 注册到绑定表
        if let Some(ref addr) = addr_a {
            BIND_TABLE.register(&UnixEndpointBound::Abstract(addr.clone()), &socket_a);
        }
        if let Some(ref addr) = addr_b {
            BIND_TABLE.register(&UnixEndpointBound::Abstract(addr.clone()), &socket_b);
        }

        (socket_a, socket_b)
    }

    pub fn ioctl_fionread(&self) -> usize {
        let inner = self.inner.lock();
        inner.recv_queue.front().map(|m| m.data.len()).unwrap_or(0)
    }

    pub fn ioctl_tiocoutq(&self) -> usize {
        // For datagram sockets, TIOCOUTQ is not relied upon by our current tests.
        // Returning 0 is consistent with an empty send queue in the common case.
        0
    }

    fn is_nonblocking(&self) -> bool {
        self.is_nonblocking.load(Ordering::Relaxed)
    }

    fn send_timeout(&self) -> Option<Duration> {
        let us = self.send_timeout_us.load(Ordering::Relaxed);
        if us == u64::MAX {
            None
        } else {
            Some(Duration::from_micros(us))
        }
    }

    fn recv_timeout(&self) -> Option<Duration> {
        let us = self.recv_timeout_us.load(Ordering::Relaxed);
        if us == u64::MAX {
            None
        } else {
            Some(Duration::from_micros(us))
        }
    }

    fn parse_u32_opt(optval: &[u8]) -> Result<u32, SystemError> {
        if optval.len() < core::mem::size_of::<u32>() {
            return Err(SystemError::EINVAL);
        }
        let mut raw = [0u8; 4];
        raw.copy_from_slice(&optval[..4]);
        Ok(u32::from_ne_bytes(raw))
    }

    fn parse_i32_opt(optval: &[u8]) -> Result<i32, SystemError> {
        if optval.len() < core::mem::size_of::<i32>() {
            return Err(SystemError::EINVAL);
        }
        let mut raw = [0u8; 4];
        raw.copy_from_slice(&optval[..4]);
        Ok(i32::from_ne_bytes(raw))
    }

    fn effective_sockbuf(requested: usize) -> usize {
        // Linux sk_{snd,rcv}buf 通常会把用户设置值放大（常见为 2x）用于 bookkeeping。
        let requested = core::cmp::max(Self::MIN_SOCKET_BUF_SIZE, requested);
        requested.saturating_mul(2)
    }

    fn send_buffer_available(&self, len: usize) -> bool {
        let sndbuf = self.sndbuf.load(Ordering::Relaxed);
        let used = self.snd_used.load(Ordering::Relaxed);
        used.saturating_add(len) <= sndbuf
    }

    fn try_account_send_buffer(&self, len: usize) -> Result<(), SystemError> {
        loop {
            let sndbuf = self.sndbuf.load(Ordering::Relaxed);
            // For datagram sockets, the whole message must fit in the send buffer.
            // If the message itself is larger than SO_SNDBUF, Linux returns EMSGSIZE.
            if len > sndbuf {
                return Err(SystemError::EMSGSIZE);
            }
            let used = self.snd_used.load(Ordering::Relaxed);
            if used.saturating_add(len) > sndbuf {
                return Err(SystemError::ENOBUFS);
            }
            if self
                .snd_used
                .compare_exchange(used, used + len, Ordering::SeqCst, Ordering::Relaxed)
                .is_ok()
            {
                return Ok(());
            }
        }
    }

    fn unaccount_send_buffer(&self, len: usize) {
        self.snd_used.fetch_sub(len, Ordering::SeqCst);
        self.wait_queue
            .wakeup(Some(crate::process::ProcessState::Blocked(true)));

        // Notify EPOLLOUT waiters that send buffer space is available again.
        let _ = EventPoll::wakeup_epoll(
            self.epoll_items().as_ref(),
            EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM,
        );
    }

    fn release_sender_accounting(sender_addr: &Option<UnixEndpointBound>, accounted_len: usize) {
        if let Some(ref addr) = sender_addr {
            if let Some(sender_socket) = BIND_TABLE.lookup(addr) {
                sender_socket.unaccount_send_buffer(accounted_len);
            }
        }
    }

    /// 发送数据报到指定地址
    fn try_send_to(
        &self,
        buffer: &[u8],
        target_addr: &UnixEndpointBound,
    ) -> Result<usize, SystemError> {
        self.try_send_to_with_rights(buffer, target_addr, Vec::new(), false)
    }

    fn try_send_to_with_rights(
        &self,
        buffer: &[u8],
        target_addr: &UnixEndpointBound,
        rights: Vec<Arc<File>>,
        force_creds: bool,
    ) -> Result<usize, SystemError> {
        if self.is_write_shutdown.load(Ordering::Acquire) {
            return Err(SystemError::EPIPE);
        }

        let buf_len = buffer.len();
        if buf_len > Self::MAX_MSG_SIZE {
            return Err(SystemError::EMSGSIZE);
        }

        // 查找目标 socket
        let target_socket = BIND_TABLE
            .lookup(target_addr)
            .ok_or(SystemError::ECONNREFUSED)?;

        if target_socket.is_read_shutdown.load(Ordering::Acquire) {
            return Err(SystemError::EPIPE);
        }

        // 获取发送方地址
        let sender_addr = { self.inner.lock().local_endpoint() };

        // 发送侧 SO_SNDBUF 记账。gVisor 用例依赖：缓冲区满时非阻塞 send 返回 EWOULDBLOCK，
        // 增大 SO_SNDBUF 后可继续 send。
        self.try_account_send_buffer(buf_len)?;

        // Attach SCM_CREDENTIALS if:
        // - sender explicitly asked via sendmsg SCM_CREDENTIALS, or
        // - SO_PASSCRED was enabled on either endpoint at send time.
        let attach_creds = force_creds
            || self.passcred.load(Ordering::Acquire)
            || target_socket.passcred.load(Ordering::Acquire);
        let creds = if attach_creds {
            Some(current_ucred())
        } else {
            None
        };

        // 创建消息
        let msg = DatagramMessage::new(buffer.to_vec(), sender_addr, rights, creds);

        // 将消息放入目标 socket 的接收队列
        {
            let mut target_inner = target_socket.inner.lock();
            if let Err(e) = target_inner.push_message(msg) {
                // 回滚记账并返回错误
                self.unaccount_send_buffer(buf_len);
                return Err(e);
            }
        }

        // 唤醒目标 socket 的等待队列
        target_socket
            .wait_queue
            .wakeup(Some(crate::process::ProcessState::Blocked(true)));

        // Notify epoll waiters: new data is readable.
        let _ = EventPoll::wakeup_epoll(
            target_socket.epoll_items().as_ref(),
            EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM,
        );

        // 发送 fasync 信号
        target_socket.fasync_items.send_sigio(FASYNC_POLL_IN);

        Ok(buf_len)
    }

    /// 从接收队列接收数据报
    ///
    /// 此函数尝试从接收队列中取出一条数据报，并将其数据复制到提供的缓冲区中。
    /// 支持通过 `peek` 参数实现 MSG_PEEK 语义（查看但不消费消息）。
    ///
    /// # 参数
    ///
    /// * `buffer` - 用于接收数据的输出缓冲区
    /// * `peek` - 是否启用 PEEK 模式。为 `true` 时仅查看消息而不从队列中移除，
    ///   也不会释放发送端的 SO_SNDBUF 记账
    ///
    /// # 返回值
    ///
    /// 成功时返回 `Ok((copy_len, sender_addr, orig_len))`，其中：
    ///
    /// * `copy_len` - 实际复制到 `buffer` 中的字节数。若缓冲区大小不足，
    ///   此值会小于消息原始长度（数据报会被静默截断）
    /// * `sender_addr` - 发送方的绑定地址。如果发送方未绑定地址则为 `None`
    /// * `orig_len` - 消息的原始长度（未截断前的字节数），可用于判断
    ///   是否发生截断以及设置 MSG_TRUNC 标志
    ///
    /// # 错误
    ///
    /// * `SystemError::EAGAIN_OR_EWOULDBLOCK` - 接收队列为空
    fn try_recv_from(
        &self,
        buffer: &mut [u8],
        peek: bool,
    ) -> Result<(usize, Option<UnixEndpointBound>, usize), SystemError> {
        let mut inner = self.inner.lock();

        if peek {
            let msg = inner
                .recv_queue
                .front()
                .ok_or(SystemError::EAGAIN_OR_EWOULDBLOCK)?;

            let orig_len = msg.data.len();

            let copy_len = core::cmp::min(buffer.len(), orig_len);
            buffer[..copy_len].copy_from_slice(&msg.data[..copy_len]);

            // MSG_PEEK must not consume the message and must not release sender accounting.
            return Ok((copy_len, msg.sender_addr.clone(), orig_len));
        }

        let msg = inner
            .pop_message()
            .ok_or(SystemError::EAGAIN_OR_EWOULDBLOCK)?;

        let orig_len = msg.data.len();

        let copy_len = core::cmp::min(buffer.len(), orig_len);
        buffer[..copy_len].copy_from_slice(&msg.data[..copy_len]);

        // 释放发送端 SO_SNDBUF 记账并唤醒等待发送者。
        Self::release_sender_accounting(&msg.sender_addr, msg.sender_accounted_len);

        // 如果缓冲区太小，数据会被截断（SOCK_DGRAM 行为）
        Ok((copy_len, msg.sender_addr, orig_len))
    }

    fn recv_return_len(copy_len: usize, orig_len: usize, flags: PMSG) -> usize {
        if flags.contains(PMSG::TRUNC) {
            orig_len
        } else {
            copy_len
        }
    }

    fn convert_enobufs_to_eagain(result: Result<usize, SystemError>) -> Result<usize, SystemError> {
        match result {
            Ok(len) => Ok(len),
            Err(SystemError::ENOBUFS) => Err(SystemError::EAGAIN_OR_EWOULDBLOCK),
            Err(e) => Err(e),
        }
    }

    fn can_recv(&self) -> bool {
        self.inner.lock().has_message()
    }
}

impl Socket for UnixDatagramSocket {
    fn netns(&self) -> Arc<crate::process::namespace::net_namespace::NetNamespace> {
        self.netns.clone()
    }

    fn fsnotify_watch_counter(&self) -> &AtomicUsize {
        &self.fsnotify_watches
    }

    fn open_file_counter(&self) -> &AtomicUsize {
        &self.open_files
    }

    fn recv_bytes_available(&self) -> usize {
        self.ioctl_fionread()
    }

    fn send_bytes_available(&self) -> Result<usize, SystemError> {
        Ok(self.ioctl_tiocoutq())
    }

    fn set_nonblocking(&self, nonblocking: bool) {
        self.is_nonblocking.store(nonblocking, Ordering::Relaxed);
    }

    fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> {
        let unix_endpoint = UnixEndpoint::try_from(endpoint)?;
        self.inner.lock().connect(unix_endpoint, &self.netns)
    }

    fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> {
        let unix_endpoint = UnixEndpoint::try_from(endpoint)?;

        // 先绑定地址
        let (bound_addr, should_register) = {
            let mut inner = self.inner.lock();
            let was_unbound = inner.local_addr.is_none();
            inner.bind(unix_endpoint, &self.netns)?;
            (inner.local_addr.clone(), was_unbound)
        };

        // 注册到绑定表（filesystem / abstract）。
        // 使用创建时保存的 Weak<Self> 来获取 Arc<Self>。
        if should_register {
            if let Some(addr) = bound_addr {
                if let Some(this) = self.self_weak.upgrade() {
                    BIND_TABLE.register(&addr, &this);
                }
            }
        }

        Ok(())
    }

    fn listen(&self, _backlog: usize) -> Result<(), SystemError> {
        // 数据报 socket 不支持 listen
        Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
    }

    fn accept(&self) -> Result<(Arc<dyn Socket>, Endpoint), SystemError> {
        // 数据报 socket 不支持 accept
        Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
    }

    fn set_option(&self, level: PSOL, optname: usize, optval: &[u8]) -> Result<(), SystemError> {
        if !matches!(level, PSOL::SOCKET) {
            return Err(SystemError::ENOPROTOOPT);
        }

        let opt = crate::net::socket::PSO::try_from(optname as u32)
            .map_err(|_| SystemError::ENOPROTOOPT)?;

        match opt {
            crate::net::socket::PSO::SNDBUF | crate::net::socket::PSO::SNDBUFFORCE => {
                let requested = Self::parse_u32_opt(optval)? as usize;
                let new_size = Self::effective_sockbuf(requested);
                self.sndbuf.store(new_size, Ordering::SeqCst);
                self.wait_queue
                    .wakeup(Some(crate::process::ProcessState::Blocked(true)));
                Ok(())
            }
            crate::net::socket::PSO::RCVBUF | crate::net::socket::PSO::RCVBUFFORCE => {
                let requested = Self::parse_u32_opt(optval)? as usize;
                let new_size = Self::effective_sockbuf(requested);
                self.rcvbuf.store(new_size, Ordering::SeqCst);
                Ok(())
            }
            crate::net::socket::PSO::SNDTIMEO_OLD | crate::net::socket::PSO::SNDTIMEO_NEW => {
                let d = parse_timeval_opt(optval)?;
                let us = d.map(|v| v.total_micros()).unwrap_or(u64::MAX);
                self.send_timeout_us.store(us, Ordering::SeqCst);
                Ok(())
            }
            crate::net::socket::PSO::RCVTIMEO_OLD | crate::net::socket::PSO::RCVTIMEO_NEW => {
                let d = parse_timeval_opt(optval)?;
                let us = d.map(|v| v.total_micros()).unwrap_or(u64::MAX);
                self.recv_timeout_us.store(us, Ordering::SeqCst);
                Ok(())
            }
            crate::net::socket::PSO::RCVLOWAT => {
                let mut v = Self::parse_i32_opt(optval)?;
                if v < 0 {
                    v = i32::MAX;
                } else if v == 0 {
                    v = 1;
                }
                self.rcvlowat.store(v, Ordering::SeqCst);
                Ok(())
            }
            crate::net::socket::PSO::PASSCRED => {
                if optval.len() < 4 {
                    return Err(SystemError::EINVAL);
                }
                let mut v = [0u8; 4];
                v.copy_from_slice(&optval[..4]);
                let on = i32::from_ne_bytes(v) != 0;
                self.passcred.store(on, Ordering::Release);
                Ok(())
            }
            _ => Err(SystemError::ENOPROTOOPT),
        }
    }

    fn wait_queue(&self) -> &WaitQueue {
        &self.wait_queue
    }

    fn local_endpoint(&self) -> Result<Endpoint, SystemError> {
        let inner = self.inner.lock();
        let addr = inner
            .local_endpoint()
            .map(|a| Endpoint::Unix(a.into()))
            .unwrap_or(Endpoint::Unix(UnixEndpoint::Unnamed));
        Ok(addr)
    }

    fn remote_endpoint(&self) -> Result<Endpoint, SystemError> {
        let inner = self.inner.lock();
        inner
            .peer_endpoint()
            .map(|a| Endpoint::Unix(a.into()))
            .ok_or(SystemError::ENOTCONN)
    }

    fn recv(&self, buffer: &mut [u8], flags: socket::PMSG) -> Result<usize, SystemError> {
        let peek = flags.contains(PMSG::PEEK);
        let nonblock = self.is_nonblocking() || flags.contains(PMSG::DONTWAIT);

        if nonblock {
            return self
                .try_recv_from(buffer, peek)
                .map(|(copy_len, _addr, orig_len)| {
                    Self::recv_return_len(copy_len, orig_len, flags)
                });
        }

        loop {
            match self.try_recv_from(buffer, peek) {
                Ok((copy_len, _addr, orig_len)) => {
                    return Ok(Self::recv_return_len(copy_len, orig_len, flags));
                }
                Err(SystemError::EAGAIN_OR_EWOULDBLOCK) => {
                    self.wait_queue.wait_event_interruptible_timeout(
                        || self.can_recv(),
                        self.recv_timeout(),
                    )?;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn recv_from(
        &self,
        buffer: &mut [u8],
        flags: socket::PMSG,
        _address: Option<Endpoint>,
    ) -> Result<(usize, Endpoint), SystemError> {
        let peek = flags.contains(PMSG::PEEK);
        let nonblock = self.is_nonblocking() || flags.contains(PMSG::DONTWAIT);

        let do_recv = |buffer: &mut [u8]| -> Result<(usize, Endpoint), SystemError> {
            let (copy_len, addr, orig_len) = self.try_recv_from(buffer, peek)?;
            let endpoint = addr
                .map(|a| Endpoint::Unix(a.into()))
                .unwrap_or(Endpoint::Unix(UnixEndpoint::Unnamed));
            let ret_len = Self::recv_return_len(copy_len, orig_len, flags);
            Ok((ret_len, endpoint))
        };

        if nonblock {
            return do_recv(buffer);
        }

        loop {
            match do_recv(buffer) {
                Ok(result) => return Ok(result),
                Err(SystemError::EAGAIN_OR_EWOULDBLOCK) => {
                    self.wait_queue.wait_event_interruptible_timeout(
                        || self.can_recv(),
                        self.recv_timeout(),
                    )?;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn read_to_user_buffer(
        &self,
        user_buffer: &mut crate::syscall::user_buffer::UserBuffer<'_>,
    ) -> Result<usize, SystemError> {
        crate::net::socket::base::read_to_user_buffer_via_kernel_buf(
            self,
            user_buffer,
            self.recv_buffer_size(),
        )
    }

    fn recv_msg(&self, msg: &mut MsgHdr, flags: socket::PMSG) -> Result<usize, SystemError> {
        // recvmsg semantics:
        // - Deliver SCM_RIGHTS if present on the next datagram.
        // - If payload is truncated, set MSG_TRUNC.
        // - If control buffer is insufficient or missing, set MSG_CTRUNC.
        // - Fill msg_name/msg_namelen when provided.

        let iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
        let mut buf = iovs.new_buf(true)?;
        let buf_cap = buf.len();

        let nonblock = self.is_nonblocking() || flags.contains(PMSG::DONTWAIT);
        let peek = flags.contains(PMSG::PEEK);

        let (payload_copy_len, sender_addr, orig_len, rights, creds) = if nonblock {
            if peek {
                let inner = self.inner.lock();
                let msg_in = inner
                    .recv_queue
                    .front()
                    .ok_or(SystemError::EAGAIN_OR_EWOULDBLOCK)?;

                let orig_len = msg_in.data.len();
                let copy_len = core::cmp::min(buf_cap, orig_len);
                buf[..copy_len].copy_from_slice(&msg_in.data[..copy_len]);

                (
                    copy_len,
                    msg_in.sender_addr.clone(),
                    orig_len,
                    msg_in.rights.clone(),
                    msg_in.creds,
                )
            } else {
                // Pop first (short lock), then copy/compute outside.
                let msg_in = {
                    let mut inner = self.inner.lock();
                    inner
                        .pop_message()
                        .ok_or(SystemError::EAGAIN_OR_EWOULDBLOCK)?
                };

                let orig_len = msg_in.data.len();
                let copy_len = core::cmp::min(buf_cap, orig_len);
                buf[..copy_len].copy_from_slice(&msg_in.data[..copy_len]);

                Self::release_sender_accounting(&msg_in.sender_addr, msg_in.sender_accounted_len);

                (
                    copy_len,
                    msg_in.sender_addr,
                    orig_len,
                    msg_in.rights,
                    msg_in.creds,
                )
            }
        } else {
            loop {
                if peek {
                    let got = {
                        let inner = self.inner.lock();
                        inner.recv_queue.front().map(|msg_in| {
                            let orig_len = msg_in.data.len();
                            let copy_len = core::cmp::min(buf_cap, orig_len);
                            buf[..copy_len].copy_from_slice(&msg_in.data[..copy_len]);
                            (
                                copy_len,
                                msg_in.sender_addr.clone(),
                                orig_len,
                                msg_in.rights.clone(),
                                msg_in.creds,
                            )
                        })
                    };
                    if let Some(v) = got {
                        break v;
                    }
                } else {
                    let popped = {
                        let mut inner = self.inner.lock();
                        inner.pop_message()
                    };
                    if let Some(msg_in) = popped {
                        let orig_len = msg_in.data.len();
                        let copy_len = core::cmp::min(buf_cap, orig_len);
                        buf[..copy_len].copy_from_slice(&msg_in.data[..copy_len]);

                        Self::release_sender_accounting(
                            &msg_in.sender_addr,
                            msg_in.sender_accounted_len,
                        );

                        break (
                            copy_len,
                            msg_in.sender_addr,
                            orig_len,
                            msg_in.rights,
                            msg_in.creds,
                        );
                    }
                }

                self.wait_queue
                    .wait_event_interruptible_timeout(|| self.can_recv(), self.recv_timeout())?;
            }
        };

        iovs.scatter_exact(&buf[..payload_copy_len])?;

        // 写回来源地址
        let endpoint = sender_addr
            .map(|a| Endpoint::Unix(a.into()))
            .unwrap_or(Endpoint::Unix(UnixEndpoint::Unnamed));
        msg.msg_namelen = endpoint.write_to_user_msghdr(msg.msg_name, msg.msg_namelen)?;

        msg.msg_flags = 0;
        if orig_len > buf_cap {
            msg.msg_flags |= PMSG::TRUNC.bits() as i32;
        }

        // Default: no control.
        let control_ptr = msg.msg_control;
        let control_len = msg.msg_controllen;
        msg.msg_controllen = 0;

        let want_creds = self.passcred.load(Ordering::Acquire);
        let has_rights = !rights.is_empty();

        if !want_creds && !has_rights {
            return Ok(Self::recv_return_len(payload_copy_len, orig_len, flags));
        }

        if control_ptr.is_null() || control_len == 0 {
            msg.msg_flags |= MSG_CTRUNC;
            return Ok(Self::recv_return_len(payload_copy_len, orig_len, flags));
        }

        let hdr_len = core::mem::size_of::<Cmsghdr>();
        let mut write_off = 0usize;

        // 1) SCM_CREDENTIALS (if enabled)
        if want_creds {
            let remaining = control_len.saturating_sub(write_off);
            if remaining < hdr_len {
                msg.msg_flags |= MSG_CTRUNC;
                msg.msg_controllen = write_off;
                return Ok(Self::recv_return_len(payload_copy_len, orig_len, flags));
            }

            let data_avail = remaining.saturating_sub(cmsg_align(hdr_len));
            let full_data_len = core::mem::size_of::<UCred>();
            let cred_copy_len = core::cmp::min(data_avail, full_data_len);

            let cred_to_send = creds.unwrap_or_else(nobody_ucred);
            let cred_bytes: &[u8] = unsafe {
                core::slice::from_raw_parts(
                    (&cred_to_send as *const UCred) as *const u8,
                    full_data_len,
                )
            };

            // Linux uses the full ucred length for CMSG_LEN/CMSG_SPACE and clamps cmsg_len
            // if the provided buffer is smaller. gVisor asserts this behavior.
            let mut buf = CmsgBuffer {
                ptr: control_ptr,
                len: control_len,
                write_off: &mut write_off,
            };
            buf.put(
                &mut msg.msg_flags,
                SOL_SOCKET,
                SCM_CREDENTIALS,
                full_data_len,
                &cred_bytes[..cred_copy_len],
            )?;
        }

        // 2) SCM_RIGHTS (if present)
        if has_rights {
            let remaining = control_len - write_off;
            let data_avail = remaining.saturating_sub(cmsg_align(hdr_len));
            let max_fds = data_avail / core::mem::size_of::<i32>();
            let fit = core::cmp::min(max_fds, rights.len());
            if fit == 0 {
                msg.msg_flags |= MSG_CTRUNC;
                msg.msg_controllen = write_off;
                return Ok(Self::recv_return_len(payload_copy_len, orig_len, flags));
            }
            if fit < rights.len() {
                msg.msg_flags |= MSG_CTRUNC;
            }

            let cloexec = flags.contains(socket::PMSG::CMSG_CLOEXEC);
            let mut received_fds: Vec<i32> = Vec::with_capacity(fit);
            {
                let fd_table_binding = ProcessManager::current_pcb().fd_table();
                let mut fd_table = fd_table_binding.write();
                for file in rights.iter().take(fit) {
                    // SCM_RIGHTS 复制的是 fd 引用，必须共享同一个 open file description。
                    let new_fd = fd_table.alloc_fd_arc(file.clone(), None, cloexec)?;
                    received_fds.push(new_fd);
                }
            }

            let data_len = received_fds.len() * core::mem::size_of::<i32>();
            let fd_bytes: &[u8] = unsafe {
                core::slice::from_raw_parts(received_fds.as_ptr() as *const u8, data_len)
            };

            let mut buf = CmsgBuffer {
                ptr: control_ptr,
                len: control_len,
                write_off: &mut write_off,
            };
            if let Err(e) = buf.put(
                &mut msg.msg_flags,
                SOL_SOCKET,
                SCM_RIGHTS,
                data_len,
                fd_bytes,
            ) {
                super::rollback_allocated_fds(&received_fds);
                return Err(e);
            }
        }

        msg.msg_controllen = write_off;

        Ok(Self::recv_return_len(payload_copy_len, orig_len, flags))
    }

    fn send(&self, buffer: &[u8], flags: socket::PMSG) -> Result<usize, SystemError> {
        // send 需要先 connect
        let peer_addr = self
            .inner
            .lock()
            .peer_endpoint()
            .ok_or(SystemError::EDESTADDRREQ)?;

        let nonblock = self.is_nonblocking() || flags.contains(PMSG::DONTWAIT);
        if nonblock {
            return Self::convert_enobufs_to_eagain(self.try_send_to(buffer, &peer_addr));
        }

        loop {
            match self.try_send_to(buffer, &peer_addr) {
                Ok(len) => return Ok(len),
                Err(SystemError::ENOBUFS) => {
                    self.wait_queue.wait_event_interruptible_timeout(
                        || self.send_buffer_available(buffer.len()),
                        self.send_timeout(),
                    )?;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn send_msg(&self, _msg: &MsgHdr, _flags: socket::PMSG) -> Result<usize, SystemError> {
        let msg = _msg;

        // Gather payload.
        let iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, false)? };
        let buf = iovs.gather()?;

        // Resolve destination.
        let target_addr = if !msg.msg_name.is_null() {
            let endpoint = crate::net::posix::SockAddr::to_endpoint(
                msg.msg_name as *const crate::net::posix::SockAddr,
                msg.msg_namelen,
            )?;
            let unix_endpoint = UnixEndpoint::try_from(endpoint)?;
            unix_endpoint.connect_in(&self.netns)?
        } else {
            self.inner
                .lock()
                .peer_endpoint()
                .ok_or(SystemError::EDESTADDRREQ)?
        };

        // Parse SCM_RIGHTS / SCM_CREDENTIALS from msg_control.
        let mut rights_files: Vec<Arc<File>> = Vec::new();
        let mut force_creds = false;
        if !msg.msg_control.is_null() && msg.msg_controllen != 0 {
            if msg.msg_controllen < core::mem::size_of::<Cmsghdr>() {
                return Err(SystemError::EINVAL);
            }

            let reader =
                UserBufferReader::new(msg.msg_control as *const u8, msg.msg_controllen, true)?;
            let mut off = 0usize;
            while off + core::mem::size_of::<Cmsghdr>() <= msg.msg_controllen {
                let hdr = reader.read_one_from_user::<Cmsghdr>(off)?;
                if hdr.cmsg_len < core::mem::size_of::<Cmsghdr>() {
                    return Err(SystemError::EINVAL);
                }
                if off + hdr.cmsg_len > msg.msg_controllen {
                    return Err(SystemError::EINVAL);
                }

                if hdr.cmsg_level == SOL_SOCKET && hdr.cmsg_type == SCM_RIGHTS {
                    let data_off = off + core::mem::size_of::<Cmsghdr>();
                    let data_len = hdr.cmsg_len - core::mem::size_of::<Cmsghdr>();
                    if !data_len.is_multiple_of(core::mem::size_of::<i32>()) {
                        return Err(SystemError::EINVAL);
                    }
                    let fd_count = data_len / core::mem::size_of::<i32>();
                    if fd_count != 0 {
                        let mut fds: Vec<i32> = vec![0; fd_count];
                        reader.copy_from_user::<i32>(&mut fds, data_off)?;

                        let fd_table_binding = ProcessManager::current_pcb().fd_table();
                        let fd_table = fd_table_binding.read();
                        for fd in fds {
                            let file = fd_table.get_file_by_fd(fd).ok_or(SystemError::EBADF)?;
                            rights_files.push(file);
                        }
                    }
                }

                if hdr.cmsg_level == SOL_SOCKET && hdr.cmsg_type == SCM_CREDENTIALS {
                    // SCM_CREDENTIALS must carry a full ucred.
                    let want = core::mem::size_of::<Cmsghdr>() + core::mem::size_of::<UCred>();
                    if hdr.cmsg_len != want {
                        return Err(SystemError::EINVAL);
                    }
                    force_creds = true;
                }

                off += cmsg_align(hdr.cmsg_len);
            }
        }

        let nonblock = self.is_nonblocking() || _flags.contains(PMSG::DONTWAIT);
        if nonblock {
            return Self::convert_enobufs_to_eagain(self.try_send_to_with_rights(
                &buf,
                &target_addr,
                rights_files,
                force_creds,
            ));
        }

        loop {
            match self.try_send_to_with_rights(
                &buf,
                &target_addr,
                rights_files.clone(),
                force_creds,
            ) {
                Ok(len) => return Ok(len),
                Err(SystemError::ENOBUFS) => {
                    self.wait_queue.wait_event_interruptible_timeout(
                        || self.send_buffer_available(buf.len()),
                        self.send_timeout(),
                    )?;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn send_to(
        &self,
        buffer: &[u8],
        flags: socket::PMSG,
        address: Endpoint,
    ) -> Result<usize, SystemError> {
        let unix_endpoint = UnixEndpoint::try_from(address)?;
        let target_addr = unix_endpoint.connect_in(&self.netns)?;

        let nonblock = self.is_nonblocking() || flags.contains(PMSG::DONTWAIT);
        if nonblock {
            return Self::convert_enobufs_to_eagain(self.try_send_to(buffer, &target_addr));
        }

        loop {
            match self.try_send_to(buffer, &target_addr) {
                Ok(len) => return Ok(len),
                Err(SystemError::ENOBUFS) => {
                    self.wait_queue.wait_event_interruptible_timeout(
                        || self.send_buffer_available(buffer.len()),
                        self.send_timeout(),
                    )?;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn validate_send_buffer_len(
        &self,
        len: usize,
        _address: Option<&Endpoint>,
    ) -> Result<(), SystemError> {
        if len > Self::MAX_MSG_SIZE {
            return Err(SystemError::EMSGSIZE);
        }
        Ok(())
    }

    fn send_buffer_size(&self) -> usize {
        self.sndbuf.load(Ordering::Relaxed)
    }

    fn recv_buffer_size(&self) -> usize {
        self.rcvbuf.load(Ordering::Relaxed)
    }

    fn epoll_items(&self) -> &EPollItems {
        &self.epitems
    }

    fn fasync_items(&self) -> &FAsyncItems {
        &self.fasync_items
    }

    fn option(&self, level: PSOL, name: usize, value: &mut [u8]) -> Result<usize, SystemError> {
        if !matches!(level, PSOL::SOCKET) {
            return Err(SystemError::ENOPROTOOPT);
        }

        let opt =
            crate::net::socket::PSO::try_from(name as u32).map_err(|_| SystemError::ENOPROTOOPT)?;
        match opt {
            crate::net::socket::PSO::TYPE => {
                let v = PSOCK::Datagram as i32;
                Ok(write_i32_getsockopt(value, v))
            }
            crate::net::socket::PSO::DOMAIN => {
                let v = AddressFamily::Unix as i32;
                Ok(write_i32_getsockopt(value, v))
            }
            crate::net::socket::PSO::PROTOCOL => {
                let v: i32 = 0;
                Ok(write_i32_getsockopt(value, v))
            }
            crate::net::socket::PSO::SNDBUF => {
                let v = self.send_buffer_size() as u32;
                Ok(write_u32_getsockopt(value, v))
            }
            crate::net::socket::PSO::RCVBUF => {
                let v = self.recv_buffer_size() as u32;
                Ok(write_u32_getsockopt(value, v))
            }
            crate::net::socket::PSO::SNDTIMEO_OLD | crate::net::socket::PSO::SNDTIMEO_NEW => {
                let us = self.send_timeout_us.load(Ordering::Relaxed);
                let us = if us == u64::MAX { 0 } else { us };
                Ok(write_timeval_opt(value, us))
            }
            crate::net::socket::PSO::RCVTIMEO_OLD | crate::net::socket::PSO::RCVTIMEO_NEW => {
                let us = self.recv_timeout_us.load(Ordering::Relaxed);
                let us = if us == u64::MAX { 0 } else { us };
                Ok(write_timeval_opt(value, us))
            }
            crate::net::socket::PSO::RCVLOWAT => {
                let v = self.rcvlowat.load(Ordering::Relaxed);
                Ok(write_i32_getsockopt(value, v))
            }
            crate::net::socket::PSO::PASSCRED => {
                let v: i32 = if self.passcred.load(Ordering::Acquire) {
                    1
                } else {
                    0
                };
                Ok(write_i32_getsockopt(value, v))
            }
            _ => Err(SystemError::ENOPROTOOPT),
        }
    }

    fn do_close(&self) -> Result<(), SystemError> {
        // 先从绑定表中注销，防止新消息进入
        let inner = self.inner.lock();
        if let Some(ref addr) = inner.local_addr {
            BIND_TABLE.unregister(addr);
        }
        drop(inner);

        // 清空接收队列并释放所有发送端记账
        // 注意：需要在获取 inner 锁之后操作，但释放记账时不能持有 inner 锁
        // 因为 release_sender_accounting 可能需要查找 BIND_TABLE
        let messages_to_release: Vec<(Option<UnixEndpointBound>, usize)> = {
            let mut inner = self.inner.lock();
            inner
                .recv_queue
                .drain(..)
                .map(|msg| (msg.sender_addr, msg.sender_accounted_len))
                .collect()
        };

        // 释放所有发送端记账（不持有 inner 锁）
        for (sender_addr, accounted_len) in messages_to_release {
            Self::release_sender_accounting(&sender_addr, accounted_len);
        }

        Ok(())
    }

    fn shutdown(&self, _how: socket::common::ShutdownBit) -> Result<(), SystemError> {
        if _how.is_recv_shutdown() {
            self.is_read_shutdown.store(true, Ordering::Release);
        }
        if _how.is_send_shutdown() {
            self.is_write_shutdown.store(true, Ordering::Release);
        }

        self.wait_queue
            .wakeup(Some(crate::process::ProcessState::Blocked(true)));
        Ok(())
    }

    fn check_io_event(&self) -> crate::filesystem::epoll::EPollEventType {
        let mut events = EPollEventType::empty();

        let inner = self.inner.lock();
        if inner.has_message() {
            events |= EPollEventType::EPOLLIN;
        }
        // 数据报 socket 总是可写的（除非队列满）
        events |= EPollEventType::EPOLLOUT;

        events
    }

    fn socket_inode_id(&self) -> InodeId {
        self.inode_id
    }
}

impl Drop for UnixDatagramSocket {
    fn drop(&mut self) {
        // 从绑定表中注销，释放地址
        let inner = self.inner.lock();
        if let Some(ref addr) = inner.local_addr {
            BIND_TABLE.unregister(addr);
        }
        // 注意：不在这里释放接收队列中的记账
        // 因为 Drop 运行时其他 socket 可能已经被 drop，访问它们不安全
        // 正常的关闭流程应该通过 do_close 完成
    }
}
