// Copyright 2018-2026 the Deno authors. MIT license.

use std::collections::VecDeque;
use std::ffi::c_char;
use std::ffi::c_int;
use std::ffi::c_uint;
use std::ffi::c_void;
use std::net::SocketAddr;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;

#[cfg(unix)]
pub(crate) use libc::AF_INET;
#[cfg(unix)]
use libc::AF_INET6;
#[cfg(unix)]
pub(crate) use libc::sockaddr_in;
#[cfg(unix)]
use libc::sockaddr_in6;
#[cfg(unix)]
type sa_family_t = libc::sa_family_t;
#[cfg(windows)]
pub(crate) use win_sock::AF_INET;
#[cfg(windows)]
use win_sock::AF_INET6;
#[cfg(windows)]
pub(crate) use win_sock::sockaddr_in;
#[cfg(windows)]
use win_sock::sockaddr_in6;

use crate::uv_compat::UV_EADDRINUSE;
use crate::uv_compat::UV_EAGAIN;
use crate::uv_compat::UV_EALREADY;
use crate::uv_compat::UV_ECANCELED;
use crate::uv_compat::UV_EINVAL;
use crate::uv_compat::UV_ENOBUFS;
use crate::uv_compat::UV_ENOTCONN;
#[cfg(unix)]
use crate::uv_compat::UV_ENOTSUP;
use crate::uv_compat::UV_EOF;
use crate::uv_compat::UV_EPIPE;
use crate::uv_compat::UV_HANDLE_ACTIVE;
use crate::uv_compat::UV_HANDLE_REF;
use crate::uv_compat::get_inner;
use crate::uv_compat::uv_alloc_cb;
use crate::uv_compat::uv_buf_t;
use crate::uv_compat::uv_connect_cb;
use crate::uv_compat::uv_connect_t;
use crate::uv_compat::uv_connection_cb;
use crate::uv_compat::uv_handle_t;
use crate::uv_compat::uv_handle_type;
use crate::uv_compat::uv_loop_t;
use crate::uv_compat::uv_read_cb;
use crate::uv_compat::uv_shutdown_cb;
use crate::uv_compat::uv_shutdown_t;
use crate::uv_compat::uv_stream_t;
use crate::uv_compat::uv_write_cb;
use crate::uv_compat::uv_write_t;
#[cfg(windows)]
type sa_family_t = win_sock::sa_family_t;

// libc doesn't export socket structs on Windows.
#[cfg(windows)]
mod win_sock {
  #[repr(C)]
  pub struct in_addr {
    pub s_addr: u32,
  }
  #[repr(C)]
  pub struct sockaddr_in {
    pub sin_family: u16,
    pub sin_port: u16,
    pub sin_addr: in_addr,
    pub sin_zero: [u8; 8],
  }
  #[repr(C)]
  pub struct in6_addr {
    pub s6_addr: [u8; 16],
  }
  #[repr(C)]
  pub struct sockaddr_in6 {
    pub sin6_family: u16,
    pub sin6_port: u16,
    pub sin6_flowinfo: u32,
    pub sin6_addr: in6_addr,
    pub sin6_scope_id: u32,
  }
  pub const AF_INET: i32 = 2;
  pub const AF_INET6: i32 = 23;
  pub type sa_family_t = u16;
}
#[repr(C)]
pub struct uv_tcp_t {
  pub r#type: uv_handle_type,
  pub loop_: *mut uv_loop_t,
  pub data: *mut c_void,
  pub flags: u32,
  #[cfg(unix)]
  pub(crate) internal_fd: Option<std::os::unix::io::RawFd>,
  #[cfg(windows)]
  pub(crate) internal_fd: Option<std::os::windows::io::RawSocket>,
  pub(crate) internal_bind_addr: Option<SocketAddr>,
  /// Pre-created socket from `uv_tcp_bind`. Consumed by `uv_listen` or
  /// `uv_tcp_connect` so the same fd is used throughout the lifecycle,
  /// preserving any socket options set between bind and listen/connect.
  pub(crate) internal_socket: Option<tokio::net::TcpSocket>,
  /// Deferred bind error (e.g. EADDRINUSE). Reported from listen/connect,
  /// matching libuv's `delayed_error` semantics.
  pub(crate) internal_delayed_error: c_int,
  pub(crate) internal_stream: Option<tokio::net::TcpStream>,
  pub(crate) internal_listener: Option<tokio::net::TcpListener>,
  pub(crate) internal_listener_addr: Option<SocketAddr>,
  pub(crate) internal_nodelay: bool,
  /// Desired SO_KEEPALIVE state `(enable, delay_secs)`. Stored so the
  /// option can be (re)applied once the underlying socket exists — e.g.
  /// when `uv_tcp_keepalive` is called before the connect future
  /// resolves, the option is applied from `poll_tcp_handle` after the
  /// stream is created. Mirrors how `internal_nodelay` is carried.
  pub(crate) internal_keepalive: Option<(bool, c_uint)>,
  pub(crate) internal_alloc_cb: Option<uv_alloc_cb>,
  pub(crate) internal_read_cb: Option<uv_read_cb>,
  pub(crate) internal_reading: bool,
  /// Set true once a non-zero read has occurred on this connection.
  /// Used by the broken-connection probe to distinguish a peer that
  /// FIN'd after sending data (legitimate half-close — write side
  /// stays valid) from a peer that aborted before sending anything
  /// (writes can't be delivered). Persists across polls.
  pub(crate) internal_received_data: bool,
  pub(crate) internal_connect: Option<ConnectPending>,
  pub(crate) internal_write_queue: VecDeque<WritePending>,
  pub(crate) internal_connection_cb: Option<uv_connection_cb>,
  pub(crate) internal_backlog: VecDeque<tokio::net::TcpStream>,
  pub(crate) internal_shutdown: Option<ShutdownPending>,
  /// Per-handle waker. Used to register interest with tokio's reactor
  /// and enqueue this handle on the loop's ready queue when the fd
  /// becomes ready. `None` on handles constructed via `new_tcp()`
  /// (tests, temporary values); real handles get one in `uv_tcp_init`.
  pub(crate) internal_waker:
    Option<std::sync::Arc<crate::uv_compat::waker::TcpHandleWaker>>,
}

impl uv_tcp_t {
  /// Detach and return the underlying TCP stream, e.g. for handing it
  /// off to a WebSocket. The caller takes ownership of the stream;
  /// subsequent reads/writes through libuv will see `None`.
  pub fn take_stream(&mut self) -> Option<tokio::net::TcpStream> {
    self.internal_stream.take()
  }
}

/// In-flight TCP connect operation.
///
/// # Safety
/// `req` is a raw pointer to a caller-owned `uv_connect_t`. The caller must
/// ensure it remains valid until the connect callback fires (at which point
/// `ConnectPending` is consumed). This struct is `!Send` -- it lives on the
/// event loop thread alongside `UvLoopInner`.
pub(crate) struct ConnectPending {
  pub(crate) future:
    Pin<Box<dyn Future<Output = std::io::Result<tokio::net::TcpStream>>>>,
  pub(crate) req: *mut uv_connect_t,
  pub(crate) cb: Option<uv_connect_cb>,
}

/// Queued write operation waiting for the socket to become writable.
///
/// # Safety
/// `req` is a raw pointer to a caller-owned `uv_write_t`. The caller must
/// ensure it remains valid until the write callback fires (at which point
/// `WritePending` is consumed). This struct is `!Send`.
pub(crate) struct WritePending {
  pub(crate) req: *mut uv_write_t,
  pub(crate) data: Vec<u8>,
  pub(crate) offset: usize,
  /// When `Some`, iovecs take precedence over `data`/`offset` for the
  /// write drain. Retention for the memory pointed to by these iovecs
  /// is the caller's responsibility (typically `stream_wrap` retains
  /// `v8::Global<v8::ArrayBuffer>` refs on the write request's
  /// callback state so the memory stays alive until the callback).
  /// `data` is kept empty in this mode.
  pub(crate) iovecs: Option<IovecCursor>,
  pub(crate) cb: Option<uv_write_cb>,
  /// Pre-determined completion status. When `Some`, the write is already
  /// complete and the callback should be fired with this status without
  /// attempting any I/O. This is used to defer synchronous write
  /// completions to the event loop, preventing re-entrancy issues.
  pub(crate) status: Option<c_int>,
}

/// Cursor over a scatter-gather write: a list of iovecs plus a head
/// index and byte offset into the head entry (entries past the head
/// are always full). Mirrors libuv's `uv__write`'s queue entry which
/// carries `(bufs, nbufs, write_index)` through the drain loop.
///
/// `head_index` lets `advance` run in O(1) per consumed iovec instead
/// of shifting the tail; matters at high iovec counts (`IOV_MAX` is
/// 1024 on Linux, reachable via chunked-encoding responses).
pub(crate) struct IovecCursor {
  pub(crate) bufs: smallvec::SmallVec<[uv_buf_t; 4]>,
  /// Index of the head entry. Entries `< head_index` are consumed and
  /// must not be read.
  pub(crate) head_index: usize,
  /// Byte offset into `bufs[head_index]` for the next write. Entries
  /// `> head_index` are always consumed whole.
  pub(crate) head_off: usize,
}

impl IovecCursor {
  pub(crate) fn new(bufs: smallvec::SmallVec<[uv_buf_t; 4]>) -> Self {
    Self {
      bufs,
      head_index: 0,
      head_off: 0,
    }
  }

  /// Unwritten slice at the head of the iovec list. Callers that can't
  /// do true scatter-gather (pipes/TTY) use this to walk one iovec at a
  /// time while still preserving zero-copy semantics.
  ///
  /// # Safety
  /// The memory pointed to by the head iovec must be valid for reads.
  pub(crate) unsafe fn head_slice(&self) -> &[u8] {
    if self.head_index >= self.bufs.len() {
      return &[];
    }
    // SAFETY: caller guarantees iovec memory is valid.
    unsafe {
      let head = &self.bufs[self.head_index];
      if head.len <= self.head_off || head.base.is_null() {
        return &[];
      }
      std::slice::from_raw_parts(
        (head.base as *const u8).add(self.head_off),
        head.len - self.head_off,
      )
    }
  }

  /// Total unwritten bytes across all iovecs.
  #[allow(dead_code, reason = "public helper for external iovec consumers")]
  pub(crate) fn remaining(&self) -> usize {
    if self.head_index >= self.bufs.len() {
      return 0;
    }
    let first = self.bufs[self.head_index].len.saturating_sub(self.head_off);
    first
      + self.bufs[self.head_index + 1..]
        .iter()
        .map(|b| b.len)
        .sum::<usize>()
  }

  pub(crate) fn is_empty(&self) -> bool {
    self.head_index >= self.bufs.len()
      || (self.head_index == self.bufs.len() - 1
        && self.head_off >= self.bufs[self.head_index].len)
  }

  /// Advance the cursor by `n` bytes written. Skips over bufs fully
  /// consumed from the front by bumping `head_index`; updates the
  /// partial-write offset for the head entry. O(consumed entries),
  /// no tail shift. Mirrors the pointer advance loop in libuv's
  /// `DoTryWrite`.
  pub(crate) fn advance(&mut self, mut n: usize) {
    while n > 0 && self.head_index < self.bufs.len() {
      let avail = self.bufs[self.head_index].len.saturating_sub(self.head_off);
      if n >= avail {
        n -= avail;
        self.head_index += 1;
        self.head_off = 0;
      } else {
        self.head_off += n;
        n = 0;
      }
    }
  }

  /// Build `IoSlice`s for the unwritten window, appending to `out`.
  /// Lifetimes borrow from `self`; pointers must remain valid (caller
  /// guarantees retention).
  ///
  /// # Safety
  /// The memory pointed to by each iovec's `base` must be valid and
  /// readable for its `len`.
  pub(crate) unsafe fn io_slices<'a>(
    &'a self,
    out: &mut smallvec::SmallVec<[std::io::IoSlice<'a>; 16]>,
  ) {
    if self.head_index >= self.bufs.len() {
      return;
    }
    // SAFETY: caller guarantees iovecs point to valid readable memory.
    unsafe {
      let head = &self.bufs[self.head_index];
      if head.len > self.head_off {
        let base = (head.base as *const u8).add(self.head_off);
        let len = head.len - self.head_off;
        out.push(std::io::IoSlice::new(std::slice::from_raw_parts(base, len)));
      }
      for buf in &self.bufs[self.head_index + 1..] {
        if !buf.base.is_null() && buf.len > 0 {
          out.push(std::io::IoSlice::new(std::slice::from_raw_parts(
            buf.base as *const u8,
            buf.len,
          )));
        }
      }
    }
  }
}

/// Pending shutdown request, deferred until the write queue drains.
///
/// # Safety
/// `req` is a raw pointer to a caller-owned `uv_shutdown_t`. The caller must
/// ensure it remains valid until the shutdown callback fires.
pub(crate) struct ShutdownPending {
  pub(crate) req: *mut uv_shutdown_t,
  pub(crate) cb: Option<uv_shutdown_cb>,
}

// Re-export from parent module for backwards compatibility within crate.
pub(crate) use super::io_error_to_uv;

/// ### Safety
/// `addr` must point to a valid `sockaddr_in` or `sockaddr_in6` with correct `sa_family`.
unsafe fn sockaddr_to_std(addr: *const c_void) -> Option<SocketAddr> {
  let sa = addr as *const libc::sockaddr;
  // SAFETY: Caller guarantees addr points to a valid sockaddr.
  let family = unsafe { (*sa).sa_family as i32 };
  if family == AF_INET {
    // SAFETY: Family is AF_INET so addr is a valid sockaddr_in.
    let sin = unsafe { &*(addr as *const sockaddr_in) };
    let ip = std::net::Ipv4Addr::from(u32::from_be(sin.sin_addr.s_addr));
    let port = u16::from_be(sin.sin_port);
    Some(SocketAddr::from((ip, port)))
  } else if family == AF_INET6 {
    // SAFETY: Family is AF_INET6 so addr is a valid sockaddr_in6.
    let sin6 = unsafe { &*(addr as *const sockaddr_in6) };
    let ip = std::net::Ipv6Addr::from(sin6.sin6_addr.s6_addr);
    let port = u16::from_be(sin6.sin6_port);
    Some(SocketAddr::from((ip, port)))
  } else {
    None
  }
}

/// ### Safety
/// `out` must be writable and large enough for `sockaddr_in` or `sockaddr_in6`.
/// `len` must be a valid, writable pointer.
unsafe fn std_to_sockaddr(addr: SocketAddr, out: *mut c_void, len: *mut c_int) {
  match addr {
    SocketAddr::V4(v4) => {
      let sin = out as *mut sockaddr_in;
      // SAFETY: Caller guarantees out is large enough for sockaddr_in.
      unsafe {
        std::ptr::write_bytes(sin, 0, 1);
        #[cfg(any(target_os = "macos", target_os = "freebsd"))]
        {
          (*sin).sin_len = std::mem::size_of::<sockaddr_in>() as u8;
        }
        (*sin).sin_family = AF_INET as sa_family_t;
        (*sin).sin_port = v4.port().to_be();
        (*sin).sin_addr.s_addr = u32::from(*v4.ip()).to_be();
        *len = std::mem::size_of::<sockaddr_in>() as c_int;
      }
    }
    SocketAddr::V6(v6) => {
      let sin6 = out as *mut sockaddr_in6;
      // SAFETY: Caller guarantees out is large enough for sockaddr_in6.
      unsafe {
        std::ptr::write_bytes(sin6, 0, 1);
        #[cfg(any(target_os = "macos", target_os = "freebsd"))]
        {
          (*sin6).sin6_len = std::mem::size_of::<sockaddr_in6>() as u8;
        }
        (*sin6).sin6_family = AF_INET6 as sa_family_t;
        (*sin6).sin6_port = v6.port().to_be();
        (*sin6).sin6_addr.s6_addr = v6.ip().octets();
        (*sin6).sin6_scope_id = v6.scope_id();
        *len = std::mem::size_of::<sockaddr_in6>() as c_int;
      }
    }
  }
}

/// ### Safety
/// `loop_` must be initialized by `uv_loop_init`. `tcp` must be a valid, writable pointer.
pub unsafe fn uv_tcp_init(loop_: *mut uv_loop_t, tcp: *mut uv_tcp_t) -> c_int {
  // SAFETY: Caller guarantees both pointers are valid.
  unsafe {
    use std::ptr::addr_of_mut;
    use std::ptr::write;
    write(addr_of_mut!((*tcp).r#type), uv_handle_type::UV_TCP);
    write(addr_of_mut!((*tcp).loop_), loop_);
    write(addr_of_mut!((*tcp).data), std::ptr::null_mut());
    write(addr_of_mut!((*tcp).flags), UV_HANDLE_REF);
    write(addr_of_mut!((*tcp).internal_fd), None);
    write(addr_of_mut!((*tcp).internal_bind_addr), None);
    write(addr_of_mut!((*tcp).internal_socket), None);
    write(addr_of_mut!((*tcp).internal_delayed_error), 0);
    write(addr_of_mut!((*tcp).internal_stream), None);
    write(addr_of_mut!((*tcp).internal_listener), None);
    write(addr_of_mut!((*tcp).internal_listener_addr), None);
    write(addr_of_mut!((*tcp).internal_nodelay), false);
    write(addr_of_mut!((*tcp).internal_keepalive), None);
    write(addr_of_mut!((*tcp).internal_alloc_cb), None);
    write(addr_of_mut!((*tcp).internal_read_cb), None);
    write(addr_of_mut!((*tcp).internal_reading), false);
    write(addr_of_mut!((*tcp).internal_received_data), false);
    write(addr_of_mut!((*tcp).internal_connect), None);
    write(addr_of_mut!((*tcp).internal_write_queue), VecDeque::new());
    write(addr_of_mut!((*tcp).internal_connection_cb), None);
    write(addr_of_mut!((*tcp).internal_backlog), VecDeque::new());
    write(addr_of_mut!((*tcp).internal_shutdown), None);
    let shared = crate::uv_compat::get_inner(loop_).shared.clone();
    let w = crate::uv_compat::waker::TcpHandleWaker::new(tcp as usize, shared);
    write(addr_of_mut!((*tcp).internal_waker), Some(w));
  }
  0
}

/// ### Safety
/// `tcp` must be a valid pointer to a `uv_tcp_t` initialized by `uv_tcp_init`.
/// `fd` must be a valid, open file descriptor / socket.
pub unsafe fn uv_tcp_open(tcp: *mut uv_tcp_t, fd: c_int) -> c_int {
  // The default open path wraps the fd as a connected `TcpStream`. Callers
  // that received a listening fd (e.g. via IPC handle passing for
  // `net.Server`) must use [`uv_tcp_open_listener`] instead — matching how
  // Node's child_process layer dispatches on `message.type`. We don't try
  // to autodetect via `SO_ACCEPTCONN` because macOS returns ENOPROTOOPT for
  // that probe.
  // SAFETY: Caller guarantees tcp is initialized and fd is valid.
  unsafe {
    #[cfg(unix)]
    {
      use std::os::unix::io::FromRawFd;
      let std_stream = std::net::TcpStream::from_raw_fd(fd);
      std_stream.set_nonblocking(true).ok();
      match tokio::net::TcpStream::from_std(std_stream) {
        Ok(stream) => {
          if (*tcp).internal_nodelay {
            stream.set_nodelay(true).ok();
          }
          (*tcp).internal_fd = Some(fd);
          (*tcp).internal_stream = Some(stream);
          0
        }
        Err(_) => UV_EINVAL,
      }
    }
    #[cfg(windows)]
    {
      use std::os::windows::io::FromRawSocket;
      let sock = fd as std::os::windows::io::RawSocket;
      let std_stream = std::net::TcpStream::from_raw_socket(sock);
      std_stream.set_nonblocking(true).ok();
      match tokio::net::TcpStream::from_std(std_stream) {
        Ok(stream) => {
          if (*tcp).internal_nodelay {
            stream.set_nodelay(true).ok();
          }
          (*tcp).internal_fd = Some(sock);
          (*tcp).internal_stream = Some(stream);
          0
        }
        Err(_) => UV_EINVAL,
      }
    }
  }
}

/// Open `tcp` from an already-listening fd (typically received via IPC
/// handle passing for `net.Server`). Mirrors how Node's child_process layer
/// dispatches on the `net.Server` handle type and constructs a fresh
/// `net.Server` around the inherited fd; libuv's underlying `listen()`
/// syscall is a no-op on a listening fd, so a subsequent `uv_listen` call
/// only needs to register the connection callback.
///
/// ### Safety
/// `tcp` must be initialized by `uv_tcp_init`. `fd` must be a valid
/// socket fd whose ownership the caller is transferring. The fd may be in
/// either BIND or LISTEN state; if not already LISTEN, this function calls
/// `listen(2)` to transition it. This handles cluster's SharedHandle case
/// where the primary binds without listening (matching libuv) and each
/// worker dups the fd via SCM_RIGHTS, then opens it as a listener.
#[cfg(unix)]
pub unsafe fn uv_tcp_open_listener(tcp: *mut uv_tcp_t, fd: c_int) -> c_int {
  use std::os::unix::io::FromRawFd;
  // SAFETY: Caller guarantees tcp is initialized and fd is valid.
  unsafe {
    // `tokio::net::TcpListener::from_std` doesn't call listen(2). If the
    // kernel fd is in BIND state (e.g. a freshly-bound primary handle that
    // SharedHandle just dup'd to us), we need to transition it before the
    // listener's accept queue is armed -- otherwise connect() against this
    // worker times out.
    let mut accepting: c_int = 0;
    let mut len = std::mem::size_of::<c_int>() as libc::socklen_t;
    let already_listening = libc::getsockopt(
      fd,
      libc::SOL_SOCKET,
      libc::SO_ACCEPTCONN,
      &mut accepting as *mut _ as *mut libc::c_void,
      &mut len,
    ) == 0
      && accepting != 0;
    if !already_listening {
      // Note: if the bind that produced this fd silently failed (libuv defers
      // EADDRINUSE), the fd is unbound and the kernel will auto-bind to
      // 0.0.0.0:0 here. Callers should detect that via getsockname() / port
      // mismatch (matches Node's `checkBindError`).
      if libc::listen(fd, 511) != 0 {
        let err = std::io::Error::last_os_error();
        return io_error_to_uv(&err);
      }
    }
    let std_listener = std::net::TcpListener::from_raw_fd(fd);
    std_listener.set_nonblocking(true).ok();
    match tokio::net::TcpListener::from_std(std_listener) {
      Ok(listener) => {
        (*tcp).internal_fd = Some(fd);
        (*tcp).internal_listener_addr = listener.local_addr().ok();
        (*tcp).internal_listener = Some(listener);
        0
      }
      Err(_) => UV_EINVAL,
    }
  }
}

const UV_TCP_REUSEPORT: u32 = 4;

/// ### Safety
/// `tcp` must be a valid pointer to an initialized `uv_tcp_t`.
///
/// Returns a dup of the underlying socket file descriptor, for use as the
/// payload of an SCM_RIGHTS cmsg on an IPC channel. The caller owns the returned
/// fd and must close it after `sendmsg` has attached it to the IPC message.
#[cfg(unix)]
pub unsafe fn uv_tcp_fd_for_ipc(tcp: *mut uv_tcp_t) -> c_int {
  use std::os::fd::AsRawFd;

  if tcp.is_null() {
    return -1;
  }

  // SAFETY: Caller guarantees tcp is initialized and valid.
  unsafe {
    let tcp = &*tcp;
    let fd = if let Some(stream) = tcp.internal_stream.as_ref() {
      stream.as_raw_fd()
    } else if let Some(listener) = tcp.internal_listener.as_ref() {
      listener.as_raw_fd()
    } else {
      tcp.internal_fd.unwrap_or(-1)
    };
    if fd < 0 {
      return -1;
    }

    let dup = libc::dup(fd);
    if dup != -1 {
      let flags = libc::fcntl(dup, libc::F_GETFD);
      if flags != -1 {
        libc::fcntl(dup, libc::F_SETFD, flags | libc::FD_CLOEXEC);
      }
    }
    dup
  }
}

/// ### Safety
/// `tcp` must be initialized by `uv_tcp_init`. `addr` must point to a valid sockaddr.
pub unsafe fn uv_tcp_bind(
  tcp: *mut uv_tcp_t,
  addr: *const c_void,
  _addrlen: u32,
  flags: u32,
) -> c_int {
  // SAFETY: Caller guarantees addr points to a valid sockaddr.
  let sock_addr = unsafe { sockaddr_to_std(addr) };
  let sa = match sock_addr {
    Some(sa) => sa,
    None => return UV_EINVAL,
  };

  // SAFETY: Caller guarantees tcp is valid and initialized.
  unsafe {
    // Match libuv: create the real socket and bind immediately rather than
    // deferring. This preserves socket identity so options set between bind
    // and listen/connect are retained on the same fd.
    let socket = if sa.is_ipv4() {
      match tokio::net::TcpSocket::new_v4() {
        Ok(s) => s,
        Err(ref e) => return io_error_to_uv(e),
      }
    } else {
      match tokio::net::TcpSocket::new_v6() {
        Ok(s) => s,
        Err(ref e) => return io_error_to_uv(e),
      }
    };

    // Match libuv: on Unix, set SO_REUSEADDR before bind so TIME_WAIT
    // sockets don't block rebinding.
    #[cfg(unix)]
    socket.set_reuseaddr(true).ok();

    // SO_REUSEPORT allows multiple sockets to bind to the same port.
    if flags & UV_TCP_REUSEPORT != 0 {
      #[cfg(unix)]
      if socket.set_reuseport(true).is_err() {
        return UV_ENOTSUP;
      }
      // On Windows, SO_REUSEADDR allows multiple sockets to bind to the
      // same port (unlike Unix where it only affects TIME_WAIT). This is
      // the Windows equivalent of SO_REUSEPORT.
      #[cfg(windows)]
      socket.set_reuseaddr(true).ok();
    } else {
      // Match libuv: on Windows, set SO_EXCLUSIVEADDRUSE to prevent other
      // sockets from binding to the same port. This is the Windows equivalent
      // of the default Unix behavior (without SO_REUSEADDR's Windows semantics
      // which would allow port sharing).
      #[cfg(windows)]
      {
        use std::os::windows::io::AsRawSocket;
        unsafe extern "system" {
          fn setsockopt(
            s: usize,
            level: c_int,
            optname: c_int,
            optval: *const c_void,
            optlen: c_int,
          ) -> c_int;
        }
        const SOL_SOCKET: c_int = 0xffff;
        const SO_EXCLUSIVEADDRUSE: c_int = -5; // ~SO_REUSEADDR
        let one: c_int = 1;
        setsockopt(
          socket.as_raw_socket() as usize,
          SOL_SOCKET,
          SO_EXCLUSIVEADDRUSE,
          &one as *const c_int as *const c_void,
          std::mem::size_of::<c_int>() as c_int,
        );
      }
    }

    // Store the raw fd so uv_tcp_nodelay etc. can
    // access the socket before it becomes a stream/listener.
    #[cfg(unix)]
    {
      use std::os::unix::io::AsRawFd;
      (*tcp).internal_fd = Some(socket.as_raw_fd());
    }
    #[cfg(windows)]
    {
      use std::os::windows::io::AsRawSocket;
      (*tcp).internal_fd = Some(socket.as_raw_socket());
    }

    match socket.bind(sa) {
      Ok(()) => {
        (*tcp).internal_delayed_error = 0;
      }
      Err(ref e) => {
        // Match libuv: EADDRINUSE is deferred (reported from listen/connect).
        // Other bind errors are returned immediately.
        if e.kind() == std::io::ErrorKind::AddrInUse {
          (*tcp).internal_delayed_error = UV_EADDRINUSE;
        } else {
          // Drop the socket (closes the fd) on real error.
          (*tcp).internal_fd = None;
          return io_error_to_uv(e);
        }
      }
    }

    (*tcp).internal_bind_addr = Some(sa);
    (*tcp).internal_socket = Some(socket);
  }
  0
}

/// ### Safety
/// `req` must be a valid, writable pointer. `tcp` must be initialized by `uv_tcp_init`.
/// `addr` must point to a valid sockaddr. `req` must remain valid until the connect callback fires.
pub unsafe fn uv_tcp_connect(
  req: *mut uv_connect_t,
  tcp: *mut uv_tcp_t,
  addr: *const c_void,
  cb: Option<uv_connect_cb>,
) -> c_int {
  // SAFETY: Caller guarantees addr points to a valid sockaddr.
  let sock_addr = unsafe { sockaddr_to_std(addr) };
  let sock_addr = match sock_addr {
    Some(sa) => sa,
    None => return UV_EINVAL,
  };

  // SAFETY: Caller guarantees req and tcp are valid.
  unsafe {
    (*req).handle = tcp as *mut uv_stream_t;
  }

  // SAFETY: tcp was initialized by uv_tcp_init which set loop_.
  let inner = unsafe { get_inner((*tcp).loop_) };

  // SAFETY: Caller guarantees tcp is valid and initialized.
  unsafe {
    // Match libuv: reject if a connect is already in progress.
    if (*tcp).internal_connect.is_some() {
      return UV_EALREADY;
    }

    // Match libuv: report deferred bind errors (e.g. EADDRINUSE).
    if (*tcp).internal_delayed_error != 0 {
      let err = (*tcp).internal_delayed_error;
      (*tcp).internal_delayed_error = 0;
      return err;
    }

    (*tcp).flags |= UV_HANDLE_ACTIVE;
    let mut handles = inner.tcp_handles.borrow_mut();
    if !handles.iter().any(|&h| std::ptr::eq(h, tcp)) {
      handles.push(tcp);
    }
    if let Some(w) = (*tcp).internal_waker.as_ref() {
      w.mark_ready();
    }

    // Take the pre-created socket from bind (if any). This preserves
    // socket identity so options set between bind and connect are retained
    // on the same fd, matching libuv's behavior.
    let socket = (*tcp).internal_socket.take();
    (*tcp).internal_connect = Some(ConnectPending {
      future: Box::pin(async move {
        let socket = match socket {
          Some(s) => s,
          None => {
            // No prior bind — create a fresh socket matching the
            // target address family.
            if sock_addr.is_ipv4() {
              tokio::net::TcpSocket::new_v4()?
            } else {
              tokio::net::TcpSocket::new_v6()?
            }
          }
        };
        socket.connect(sock_addr).await
      }),
      req,
      cb,
    });
  }

  0
}

/// ### Safety
/// `tcp` must be a valid pointer to a `uv_tcp_t` initialized by `uv_tcp_init`.
pub unsafe fn uv_tcp_nodelay(tcp: *mut uv_tcp_t, enable: c_int) -> c_int {
  // SAFETY: Caller guarantees tcp is valid and initialized.
  unsafe {
    let enabled = enable != 0;
    (*tcp).internal_nodelay = enabled;
    if let Some(ref stream) = (*tcp).internal_stream {
      if stream.set_nodelay(enabled).is_err() {
        return UV_EINVAL;
      }
    } else if (*tcp).internal_fd.is_some() {
      // Socket exists from bind but isn't a stream yet. Apply nodelay
      // on the raw fd so the option is preserved, matching libuv's
      // uv__stream_open which applies TCP_NODELAY on the socket fd.
      let on: c_int = if enabled { 1 } else { 0 };
      #[cfg(unix)]
      {
        let fd = (*tcp).internal_fd.unwrap();
        if libc::setsockopt(
          fd,
          libc::IPPROTO_TCP,
          libc::TCP_NODELAY,
          &on as *const c_int as *const c_void,
          std::mem::size_of::<c_int>() as libc::socklen_t,
        ) != 0
        {
          return UV_EINVAL;
        }
      }
      #[cfg(windows)]
      {
        // On Windows, nodelay will be applied when the stream is created.
        // TcpSocket doesn't expose setsockopt directly.
        let _ = on;
      }
    }
  }
  0
}

/// Set SO_LINGER to 0 on the TCP socket and close it immediately so
/// the OS sends RST instead of FIN.  This matches libuv's
/// `uv_tcp_close_reset`.
///
/// The stream is taken and dropped here rather than in `stop_tcp`,
/// because `stop_tcp` calls `shutdown(Both)` which sends FIN and
/// defeats the RST behaviour.
///
/// ### Safety
/// `tcp` must be a valid pointer to a `uv_tcp_t` initialized by `uv_tcp_init`.
pub unsafe fn uv_tcp_reset(tcp: *mut uv_tcp_t) -> c_int {
  // SAFETY: Caller guarantees tcp is valid and initialized.
  unsafe {
    if let Some(ref stream) = (*tcp).internal_stream
      && stream.set_linger(Some(std::time::Duration::ZERO)).is_err()
    {
      return UV_EINVAL;
    }
    // Drop the stream immediately so the fd is closed with SO_LINGER=0,
    // causing the kernel to send RST to the peer.  `stop_tcp` will find
    // `internal_stream` already `None` and skip the graceful shutdown.
    let _ = (*tcp).internal_stream.take();
  }
  0
}

/// ### Safety
/// `tcp` must be initialized by `uv_tcp_init`. `name` must be writable and large enough
/// for a sockaddr. `namelen` must be a valid, writable pointer.
pub unsafe fn uv_tcp_getpeername(
  tcp: *const uv_tcp_t,
  name: *mut c_void,
  namelen: *mut c_int,
) -> c_int {
  // SAFETY: Caller guarantees all pointers are valid.
  unsafe {
    if let Some(ref stream) = (*tcp).internal_stream {
      match stream.peer_addr() {
        Ok(addr) => {
          std_to_sockaddr(addr, name, namelen);
          0
        }
        Err(_) => UV_ENOTCONN,
      }
    } else {
      UV_ENOTCONN
    }
  }
}

/// ### Safety
/// `tcp` must be initialized by `uv_tcp_init`. `name` must be writable and large enough
/// for a sockaddr. `namelen` must be a valid, writable pointer.
pub unsafe fn uv_tcp_getsockname(
  tcp: *const uv_tcp_t,
  name: *mut c_void,
  namelen: *mut c_int,
) -> c_int {
  // SAFETY: Caller guarantees all pointers are valid.
  unsafe {
    if let Some(ref stream) = (*tcp).internal_stream {
      match stream.local_addr() {
        Ok(addr) => {
          std_to_sockaddr(addr, name, namelen);
          return 0;
        }
        Err(_) => return UV_EINVAL,
      }
    }
    if let Some(addr) = (*tcp).internal_listener_addr {
      std_to_sockaddr(addr, name, namelen);
      return 0;
    }
    // Query the pre-created socket's actual bound address. This correctly
    // resolves ephemeral port 0 to the real port assigned by the OS.
    if let Some(ref socket) = (*tcp).internal_socket
      && let Ok(addr) = socket.local_addr()
    {
      std_to_sockaddr(addr, name, namelen);
      return 0;
    }
    if let Some(addr) = (*tcp).internal_bind_addr {
      std_to_sockaddr(addr, name, namelen);
      return 0;
    }
    UV_EINVAL
  }
}

/// Apply `SO_KEEPALIVE` (and, when enabling, the idle delay) to a raw
/// socket descriptor. Mirrors libuv's `uv__tcp_keepalive`: toggle
/// `SO_KEEPALIVE`, then set the per-connection idle time via the
/// platform's TCP keepalive-idle option. Returns 0 on success or a
/// negative uv error code.
///
/// ### Safety
/// `fd` must be a valid, open socket descriptor.
#[cfg(unix)]
unsafe fn apply_keepalive_fd(
  fd: std::os::unix::io::RawFd,
  enable: bool,
  delay: c_uint,
) -> c_int {
  // SAFETY: fd is a valid socket per the caller contract.
  unsafe {
    let on: c_int = if enable { 1 } else { 0 };
    if libc::setsockopt(
      fd,
      libc::SOL_SOCKET,
      libc::SO_KEEPALIVE,
      &on as *const c_int as *const c_void,
      std::mem::size_of::<c_int>() as libc::socklen_t,
    ) != 0
    {
      return io_error_to_uv(&std::io::Error::last_os_error());
    }

    // The idle delay is only meaningful when keepalive is enabled.
    // Linux/Android use TCP_KEEPIDLE; the BSDs/macOS use TCP_KEEPALIVE.
    // Both take the idle time in seconds. On any other platform we leave
    // SO_KEEPALIVE on with the system default idle time (still correct).
    #[cfg(any(target_os = "linux", target_os = "android"))]
    let idle_opt: Option<c_int> = Some(libc::TCP_KEEPIDLE);
    #[cfg(any(
      target_os = "macos",
      target_os = "ios",
      target_os = "freebsd",
      target_os = "netbsd",
      target_os = "openbsd",
      target_os = "dragonfly"
    ))]
    let idle_opt: Option<c_int> = Some(libc::TCP_KEEPALIVE);
    #[cfg(not(any(
      target_os = "linux",
      target_os = "android",
      target_os = "macos",
      target_os = "ios",
      target_os = "freebsd",
      target_os = "netbsd",
      target_os = "openbsd",
      target_os = "dragonfly"
    )))]
    let idle_opt: Option<c_int> = None;

    if enable
      && delay > 0
      && let Some(idle_opt) = idle_opt
    {
      let secs = delay as c_int;
      if libc::setsockopt(
        fd,
        libc::IPPROTO_TCP,
        idle_opt,
        &secs as *const c_int as *const c_void,
        std::mem::size_of::<c_int>() as libc::socklen_t,
      ) != 0
      {
        return io_error_to_uv(&std::io::Error::last_os_error());
      }
    }
  }
  0
}

/// Windows variant: toggle `SO_KEEPALIVE`. The idle interval can only be
/// configured via `WSAIoctl(SIO_KEEPALIVE_VALS)`, which libuv uses; we
/// keep to the on/off toggle (matching the system default idle time),
/// which is what consumers like tedious rely on to keep tunneled
/// connections from being reaped by intermediaries.
///
/// ### Safety
/// `sock` must be a valid socket handle.
#[cfg(windows)]
unsafe fn apply_keepalive_socket(
  sock: usize,
  enable: bool,
  _delay: c_uint,
) -> c_int {
  unsafe extern "system" {
    fn setsockopt(
      s: usize,
      level: c_int,
      optname: c_int,
      optval: *const c_void,
      optlen: c_int,
    ) -> c_int;
  }
  const SOL_SOCKET: c_int = 0xffff;
  const SO_KEEPALIVE: c_int = 0x0008;
  let on: c_int = if enable { 1 } else { 0 };
  // SAFETY: sock is a valid socket per the caller contract.
  let rc = unsafe {
    setsockopt(
      sock,
      SOL_SOCKET,
      SO_KEEPALIVE,
      &on as *const c_int as *const c_void,
      std::mem::size_of::<c_int>() as c_int,
    )
  };
  if rc != 0 {
    return io_error_to_uv(&std::io::Error::last_os_error());
  }
  0
}

/// Apply the stored keepalive option to a connected stream's socket.
/// Called from `poll_tcp_handle` once the connect future resolves so a
/// `uv_tcp_keepalive` issued before connect completion still takes
/// effect. No-op when no keepalive was requested.
///
/// ### Safety
/// `tcp` must be a valid pointer to an initialized `uv_tcp_t`.
pub(crate) unsafe fn apply_pending_keepalive(tcp: *mut uv_tcp_t) {
  // SAFETY: tcp is valid and initialized per the caller contract.
  unsafe {
    let Some((enable, delay)) = (*tcp).internal_keepalive else {
      return;
    };
    #[cfg(unix)]
    if let Some(ref stream) = (*tcp).internal_stream {
      use std::os::unix::io::AsRawFd;
      apply_keepalive_fd(stream.as_raw_fd(), enable, delay);
    }
    #[cfg(windows)]
    if let Some(ref stream) = (*tcp).internal_stream {
      use std::os::windows::io::AsRawSocket;
      apply_keepalive_socket(stream.as_raw_socket() as usize, enable, delay);
    }
  }
}

/// Enable or disable TCP keepalive on the handle, applying it to the
/// underlying socket when one already exists. Mirrors libuv's
/// `uv_tcp_keepalive`. The requested state is also stored so it is
/// applied if/when the socket is created later (e.g. a keepalive set
/// while the connect is still pending). `delay` is the idle time in
/// seconds before the first keepalive probe.
///
/// ### Safety
/// `tcp` must be a valid pointer to a `uv_tcp_t` initialized by `uv_tcp_init`.
#[cfg_attr(feature = "uv_compat_export", unsafe(no_mangle))]
pub unsafe extern "C" fn uv_tcp_keepalive(
  tcp: *mut uv_tcp_t,
  enable: c_int,
  delay: c_uint,
) -> c_int {
  // SAFETY: tcp is valid and initialized per the caller contract.
  unsafe {
    let enabled = enable != 0;
    (*tcp).internal_keepalive = Some((enabled, delay));

    #[cfg(unix)]
    {
      use std::os::unix::io::AsRawFd;
      // Prefer the live stream's fd; fall back to the pre-connect socket
      // fd recorded by bind so an option set between bind and connect is
      // preserved on the same descriptor (matching uv__stream_open).
      let fd = if let Some(ref stream) = (*tcp).internal_stream {
        Some(stream.as_raw_fd())
      } else {
        (*tcp).internal_fd
      };
      if let Some(fd) = fd {
        return apply_keepalive_fd(fd, enabled, delay);
      }
    }
    #[cfg(windows)]
    {
      use std::os::windows::io::AsRawSocket;
      let sock = if let Some(ref stream) = (*tcp).internal_stream {
        Some(stream.as_raw_socket() as usize)
      } else {
        (*tcp).internal_fd.map(|s| s as usize)
      };
      if let Some(sock) = sock {
        return apply_keepalive_socket(sock, enabled, delay);
      }
    }
  }
  // No socket yet: state stored, will be applied on connect.
  0
}

/// ### Safety
/// `_tcp` must be a valid pointer to a `uv_tcp_t` initialized by `uv_tcp_init`.
#[cfg_attr(feature = "uv_compat_export", unsafe(no_mangle))]
pub unsafe extern "C" fn uv_tcp_simultaneous_accepts(
  _tcp: *mut uv_tcp_t,
  _enable: c_int,
) -> c_int {
  0 // no-op
}

/// ### Safety
/// `ip` must be a valid, null-terminated C string. `addr` must be a valid, writable pointer.
#[cfg_attr(feature = "uv_compat_export", unsafe(no_mangle))]
pub unsafe extern "C" fn uv_ip4_addr(
  ip: *const c_char,
  port: c_int,
  addr: *mut sockaddr_in,
) -> c_int {
  // SAFETY: Caller guarantees ip is a valid C string and addr is writable.
  unsafe {
    let c_str = std::ffi::CStr::from_ptr(ip);
    let Ok(s) = c_str.to_str() else {
      return UV_EINVAL;
    };
    let Ok(ip_addr) = s.parse::<std::net::Ipv4Addr>() else {
      return UV_EINVAL;
    };
    std::ptr::write_bytes(addr, 0, 1);
    #[cfg(any(target_os = "macos", target_os = "freebsd"))]
    {
      (*addr).sin_len = std::mem::size_of::<sockaddr_in>() as u8;
    }
    (*addr).sin_family = AF_INET as sa_family_t;
    (*addr).sin_port = (port as u16).to_be();
    (*addr).sin_addr.s_addr = u32::from(ip_addr).to_be();
    0
  }
}

/// ### Safety
/// `stream` must be a valid pointer to a `uv_tcp_t` (cast as `uv_stream_t`) initialized
/// by `uv_tcp_init`, with a bind address set via `uv_tcp_bind`.
pub unsafe fn uv_listen(
  stream: *mut uv_stream_t,
  backlog: c_int,
  cb: Option<uv_connection_cb>,
) -> c_int {
  // SAFETY: Caller guarantees stream is a valid, initialized uv_tcp_t.
  unsafe {
    let tcp = stream as *mut uv_tcp_t;
    let tcp_ref = &mut *tcp;

    // Match libuv: report deferred bind errors.
    if tcp_ref.internal_delayed_error != 0 {
      let err = tcp_ref.internal_delayed_error;
      tcp_ref.internal_delayed_error = 0;
      return err;
    }

    // If the handle was opened from an already-listening fd (received via
    // IPC handle passing), skip bind/listen and just register the callback.
    // libuv's `listen(fd, backlog)` on an already-listening socket is a
    // no-op too.
    if tcp_ref.internal_listener.is_none() {
      let effective_backlog = if backlog > 0 { backlog as u32 } else { 128 };

      // Take the pre-created socket from bind (if any). This preserves socket
      // identity so options set between bind and listen are retained on the
      // same fd, matching libuv's behavior.
      let socket = match tcp_ref.internal_socket.take() {
        Some(s) => s,
        None => {
          // No prior bind — create a socket and bind to 0.0.0.0:0,
          // matching libuv's implicit bind in uv__tcp_listen.
          let bind_addr = tcp_ref
            .internal_bind_addr
            .unwrap_or_else(|| "0.0.0.0:0".parse().unwrap());
          let s = if bind_addr.is_ipv4() {
            match tokio::net::TcpSocket::new_v4() {
              Ok(s) => s,
              Err(ref e) => return io_error_to_uv(e),
            }
          } else {
            match tokio::net::TcpSocket::new_v6() {
              Ok(s) => s,
              Err(ref e) => return io_error_to_uv(e),
            }
          };
          s.set_reuseaddr(true).ok();
          if let Err(ref e) = s.bind(bind_addr) {
            return io_error_to_uv(e);
          }
          s
        }
      };

      let tokio_listener = match socket.listen(effective_backlog) {
        Ok(l) => l,
        Err(ref e) => return io_error_to_uv(e),
      };

      let listener_addr = tokio_listener.local_addr().ok();
      tcp_ref.internal_listener = Some(tokio_listener);
      tcp_ref.internal_listener_addr = listener_addr;
    }

    tcp_ref.internal_connection_cb = cb;
    tcp_ref.flags |= UV_HANDLE_ACTIVE;

    let inner = get_inner(tcp_ref.loop_);
    let mut handles = inner.tcp_handles.borrow_mut();
    if !handles.iter().any(|&h| std::ptr::eq(h, tcp)) {
      handles.push(tcp);
    }
    if let Some(w) = tcp_ref.internal_waker.as_ref() {
      w.mark_ready();
    }
  }
  0
}

/// ### Safety
/// `server` must be a listening `uv_tcp_t`. `client` must be initialized by `uv_tcp_init`.
pub unsafe fn uv_accept(
  server: *mut uv_stream_t,
  client: *mut uv_stream_t,
) -> c_int {
  // SAFETY: Caller guarantees both pointers are valid, initialized uv_tcp_t handles.
  unsafe {
    let server_tcp = &mut *(server as *mut uv_tcp_t);
    let client_tcp = &mut *(client as *mut uv_tcp_t);

    match server_tcp.internal_backlog.pop_front() {
      Some(stream) => {
        if client_tcp.internal_nodelay {
          stream.set_nodelay(true).ok();
        }
        client_tcp.internal_stream = Some(stream);
        0
      }
      None => UV_EAGAIN,
    }
  }
}

pub fn new_tcp() -> uv_tcp_t {
  uv_tcp_t {
    r#type: uv_handle_type::UV_TCP,
    loop_: std::ptr::null_mut(),
    data: std::ptr::null_mut(),
    flags: 0,
    internal_fd: None,
    internal_bind_addr: None,
    internal_socket: None,
    internal_delayed_error: 0,
    internal_stream: None,
    internal_listener: None,
    internal_listener_addr: None,
    internal_nodelay: false,
    internal_keepalive: None,
    internal_alloc_cb: None,
    internal_read_cb: None,
    internal_reading: false,
    internal_received_data: false,
    internal_connect: None,
    internal_write_queue: VecDeque::new(),
    internal_connection_cb: None,
    internal_backlog: VecDeque::new(),
    internal_shutdown: None,
    internal_waker: None,
  }
}

/// Poll a single TCP handle for I/O readiness and fire callbacks.
/// Returns `true` if any work was completed.
///
/// # Safety
/// `tcp_ptr` must be a valid pointer to an initialized `uv_tcp_t`.
///
/// This function carefully avoids holding `&mut uv_tcp_t` references across
/// callback invocations. Callbacks may re-enter uv_* functions that access
/// the same handle through raw pointers, so any live `&mut` would violate
/// Rust's aliasing rules.
pub(crate) unsafe fn poll_tcp_handle(
  tcp_ptr: *mut uv_tcp_t,
  cx: &mut Context<'_>,
) -> bool {
  let mut any_work = false;

  // 1. Poll pending connect.
  //    Extract result with a short-lived borrow, then call callback with
  //    no outstanding references.
  let connect_result = unsafe {
    if let Some(ref mut pending) = (*tcp_ptr).internal_connect {
      match pending.future.as_mut().poll(cx) {
        Poll::Ready(result) => Some((pending.req, pending.cb, result)),
        Poll::Pending => None,
      }
    } else {
      None
    }
  };
  if let Some((req, cb, result)) = connect_result {
    any_work = true;
    // SAFETY: tcp_ptr is valid, no outstanding borrows.
    unsafe {
      let status = match result {
        Ok(stream) => {
          if (*tcp_ptr).internal_nodelay {
            stream.set_nodelay(true).ok();
          }
          (*tcp_ptr).internal_stream = Some(stream);
          // Apply a keepalive option requested before the connect
          // resolved, now that the socket exists.
          apply_pending_keepalive(tcp_ptr);
          0
        }
        Err(ref e) => io_error_to_uv(e),
      };
      (*tcp_ptr).internal_connect = None;
      (*req).handle = tcp_ptr as *mut uv_stream_t;
      if let Some(cb) = cb {
        cb(req, status);
      }
      // Match libuv's uv__stream_connect: on connect failure, flush the
      // write queue with UV_ECANCELED so writers aren't left hanging.
      if status < 0 {
        while let Some(pw) = (*tcp_ptr).internal_write_queue.pop_front() {
          if let Some(wcb) = pw.cb {
            wcb(pw.req, UV_ECANCELED);
          }
        }
      }

      // After connect completes, clear ACTIVE if no I/O is pending.
      // The connect path sets ACTIVE, but if the JS side doesn't start
      // reading (e.g. socket.pause() before connect), the flag must be
      // cleared so the handle doesn't keep the event loop alive.
      crate::uv_compat::stream::maybe_clear_tcp_active(tcp_ptr);
    }
  }

  // 2. Poll listener for new connections.
  //    Drain all ready connections from poll_accept before firing callbacks.
  //    This prevents starvation under high concurrency: tokio's reactor
  //    only re-polls epoll when poll_event_loop_inner returns Pending, so
  //    connections that arrived during the same epoll batch must be accepted
  //    now or they'll be invisible until the next reactor turn.
  //    After draining, fire the connection callback once per accepted stream
  //    (libuv fires the callback once per connection). If the user doesn't
  //    call uv_accept in the callback, stop firing to avoid spinning.
  unsafe {
    if (*tcp_ptr).internal_listener.is_some()
      && (*tcp_ptr).internal_connection_cb.is_some()
      && (*tcp_ptr).internal_backlog.is_empty()
    {
      let listener = (*tcp_ptr).internal_listener.as_ref().unwrap();
      while let Poll::Ready(Ok((stream, _))) = listener.poll_accept(cx) {
        (*tcp_ptr).internal_backlog.push_back(stream);
        any_work = true;
      }
    }
    while !(*tcp_ptr).internal_backlog.is_empty() {
      let backlog_len = (*tcp_ptr).internal_backlog.len();
      if let Some(cb) = (*tcp_ptr).internal_connection_cb {
        cb(tcp_ptr as *mut uv_stream_t, 0);
      }
      // If the callback did not call uv_accept (backlog didn't shrink),
      // stop firing to avoid an infinite loop.
      if (*tcp_ptr).internal_backlog.len() >= backlog_len {
        break;
      }
    }
  }

  // 3. Poll readable stream.
  //    Copy the callback pointers out first (they're Copy). Then in the
  //    loop, each try_read creates a short-lived borrow that is dropped
  //    before the read_cb fires.
  //
  //    Match libuv: limit to 32 reads per poll to prevent starvation.
  //    On EAGAIN/WouldBlock, call read_cb(nread=0) so the user can free
  //    the buffer. On null alloc, call read_cb(UV_ENOBUFS).
  unsafe {
    if (*tcp_ptr).internal_reading && (*tcp_ptr).internal_stream.is_some() {
      let alloc_cb = (*tcp_ptr).internal_alloc_cb;
      let read_cb = (*tcp_ptr).internal_read_cb;
      if let (Some(alloc_cb), Some(read_cb)) = (alloc_cb, read_cb) {
        // Register interest so tokio's reactor wakes us.
        if let Some(ref stream) = (*tcp_ptr).internal_stream {
          let _ = stream.poll_read_ready(cx);
        }

        // Prevent loop starvation (matches libuv's count=32 in uv__read).
        let mut count = 32;
        loop {
          // Re-check after each callback: the callback may have
          // called uv_close or uv_read_stop.
          if !(*tcp_ptr).internal_reading
            || (*tcp_ptr).internal_stream.is_none()
          {
            break;
          }
          let mut buf = uv_buf_t {
            base: std::ptr::null_mut(),
            len: 0,
          };
          alloc_cb(tcp_ptr as *mut uv_handle_t, 65536, &mut buf);
          if buf.base.is_null() || buf.len == 0 {
            // Match libuv: report UV_ENOBUFS so the user knows alloc
            // failed, rather than silently dropping.
            read_cb(tcp_ptr as *mut uv_stream_t, UV_ENOBUFS as isize, &buf);
            break;
          }
          let slice =
            std::slice::from_raw_parts_mut(buf.base.cast::<u8>(), buf.len);
          // Short-lived borrow for try_read; dropped before callback.
          let read_result =
            (*tcp_ptr).internal_stream.as_ref().unwrap().try_read(slice);
          match read_result {
            Ok(0) => {
              read_cb(tcp_ptr as *mut uv_stream_t, UV_EOF as isize, &buf);
              (*tcp_ptr).internal_reading = false;
              crate::uv_compat::stream::maybe_clear_tcp_active(tcp_ptr);
              break;
            }
            Ok(n) => {
              any_work = true;
              (*tcp_ptr).internal_received_data = true;
              read_cb(tcp_ptr as *mut uv_stream_t, n as isize, &buf);
              count -= 1;
              if count == 0 {
                break;
              }
              // NOTE: libuv (uv__read) breaks here when `n < buf.len`
              // to skip the predicted-EAGAIN syscall. We deliberately
              // do NOT — keep looping until try_read returns
              // WouldBlock.
              //
              // Tokio's TcpStream readiness is edge-triggered: the
              // internal "readable" bit is cleared only by a
              // WouldBlock return from try_read. Breaking on partial
              // read leaves the bit armed, the re-register check at
              // the end of this function then sees `poll_read_ready
              // == Ready`, and `mark_ready()` puts the handle back
              // on the ready queue.
              //
              // Under sustained HTTP keep-alive load that turns into
              // a self-wake loop: every tick re-queues every active
              // connection, so tokio's executor sees us continuously
              // awoken and never yields to its reactor (event_interval
              // controls when the reactor is polled). New TCP
              // readiness from the kernel piles up undelivered,
              // pushing p99 from ~3 ms to ~30 ms at 100 connections
              // for short responses where every read is partial.
              //
              // Looping one more iteration costs an extra recv()
              // syscall, but that recv returns WouldBlock, clears
              // tokio's readiness bit, and lets the handle fall out
              // of the ready queue until tokio actually delivers
              // fresh readiness.
            }
            Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
              // Match libuv: call read_cb with nread=0 so the user
              // can free the buffer allocated by alloc_cb.
              read_cb(tcp_ptr as *mut uv_stream_t, 0, &buf);
              break;
            }
            Err(ref e) => {
              // Match libuv's uv__process_tcp_read_req on Windows: translate
              // WSAECONNABORTED to UV_ECONNRESET so consumers see the same
              // error code as on Unix when the peer aborts the connection.
              // Node.js's socketOnError in http2 explicitly ignores
              // ECONNRESET (but not ECONNABORTED) after GOAWAY; without this
              // mapping the test-http2-compat-serverrequest-end.js test (and
              // others that rely on the close/GOAWAY race) surface an
              // uncaught read error on Windows.
              let status = {
                let raw = io_error_to_uv(e);
                #[cfg(windows)]
                {
                  if raw == crate::uv_compat::UV_ECONNABORTED {
                    crate::uv_compat::UV_ECONNRESET
                  } else {
                    raw
                  }
                }
                #[cfg(not(windows))]
                {
                  raw
                }
              };
              read_cb(tcp_ptr as *mut uv_stream_t, status as isize, &buf);
              (*tcp_ptr).internal_reading = false;
              crate::uv_compat::stream::maybe_clear_tcp_active(tcp_ptr);
              break;
            }
          }
        }
      }
    }
  }

  // 4. Drain write queue in order.
  //    Match libuv's two-phase approach: uv__write() processes writes and
  //    collects completions, then uv__write_callbacks() fires all callbacks
  //    after the write loop. This ensures multiple writes can complete in
  //    one tick and callbacks see a consistent state.
  //
  //    Completed writes are collected into a local vec, then callbacks are
  //    fired after the write loop finishes (no outstanding borrows).
  let mut completed_writes: Vec<(*mut uv_write_t, Option<uv_write_cb>, c_int)> =
    Vec::new();
  unsafe {
    if !(*tcp_ptr).internal_write_queue.is_empty()
      && (*tcp_ptr).internal_stream.is_some()
    {
      if let Some(ref stream) = (*tcp_ptr).internal_stream {
        let _ = stream.poll_write_ready(cx);

        // Also poll read readiness when writes are pending. This ensures
        // we detect a broken connection (peer close / RST) promptly via
        // the readable side, rather than waiting for a TCP retransmit
        // timeout on the write side.
        //
        // Gate on `!internal_received_data`: if the peer has ever sent
        // us a byte, treat a subsequent FIN as a legitimate half-close
        // (write side stays valid — the peer just stopped sending).
        // Without this gate the perf-fix's single-poll EOF observation
        // turns test-net-allow-half-open's queued 'asd' write into a
        // spurious EPIPE: the read loop now consumes the server's
        // 1024 bytes and the peer FIN in the same poll, so by the time
        // this probe runs `internal_reading` is already false and the
        // FIN looks indistinguishable from a peer that aborted before
        // ever writing. `internal_received_data` resolves the ambiguity.
        if !(*tcp_ptr).internal_reading
          && !(*tcp_ptr).internal_received_data
          && let Poll::Ready(Ok(())) = stream.poll_read_ready(cx)
        {
          // Read side is ready -- peek (without consuming) to check
          // for EOF or errors. Using MSG_PEEK avoids consuming data
          // that might belong to a higher-level protocol (e.g. TLS).
          #[cfg(unix)]
          let n = {
            use std::os::unix::io::AsRawFd;
            let fd = stream.as_raw_fd();
            let mut probe = [0u8; 1];
            libc::recv(fd, probe.as_mut_ptr() as *mut c_void, 1, libc::MSG_PEEK)
              as i32
          };
          #[cfg(windows)]
          let n = {
            use std::os::windows::io::AsRawSocket;
            unsafe extern "system" {
              fn recv(
                s: usize,
                buf: *mut c_void,
                len: c_int,
                flags: c_int,
              ) -> c_int;
            }
            const MSG_PEEK: c_int = 0x2;
            let socket = stream.as_raw_socket() as usize;
            let mut probe = [0u8; 1];
            recv(socket, probe.as_mut_ptr() as *mut c_void, 1, MSG_PEEK)
          };
          if n == 0 {
            // EOF — the connection is broken.
            // Drain the entire write queue with EPIPE.
            while let Some(pw) = (*tcp_ptr).internal_write_queue.pop_front() {
              completed_writes.push((pw.req, pw.cb, UV_EPIPE));
            }
          } else if n < 0 {
            let err =
              std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
            #[cfg(unix)]
            let would_block = err == libc::EAGAIN || err == libc::EWOULDBLOCK;
            #[cfg(windows)]
            let would_block = err == 10035; // WSAEWOULDBLOCK
            if !would_block {
              // Real error — connection is broken.
              while let Some(pw) = (*tcp_ptr).internal_write_queue.pop_front() {
                completed_writes.push((pw.req, pw.cb, UV_EPIPE));
              }
            }
            // EAGAIN/EWOULDBLOCK means no data yet, connection alive
          }
          // n > 0 means data available, connection alive (data not consumed)
        }
      }

      // Match libuv's count=32 limit to prevent starvation.
      let mut count = 32;
      loop {
        if (*tcp_ptr).internal_write_queue.is_empty()
          || (*tcp_ptr).internal_stream.is_none()
        {
          break;
        }

        // Try writing in a limited scope.
        let (done, error) = {
          let stream = (*tcp_ptr).internal_stream.as_ref().unwrap();
          let pw = (*tcp_ptr).internal_write_queue.front_mut().unwrap();
          let mut done = false;
          let mut error = false;
          if let Some(ref mut iov) = pw.iovecs {
            // Scatter-gather write. Loop until drained, WouldBlock, or
            // error — mirrors uv__write's write-all-the-bytes-you-can
            // inner loop.
            loop {
              if iov.is_empty() {
                done = true;
                break;
              }
              // Scope the IoSlice borrow so we can advance `iov`
              // afterwards.
              let write_result = {
                let mut slices: smallvec::SmallVec<[std::io::IoSlice; 16]> =
                  smallvec::SmallVec::new();
                // SAFETY: iovec memory is kept alive by caller retention.
                iov.io_slices(&mut slices);
                if slices.is_empty() {
                  None
                } else {
                  Some(stream.try_write_vectored(&slices))
                }
              };
              match write_result {
                None => {
                  done = true;
                  break;
                }
                Some(Ok(0)) => break,
                Some(Ok(n)) => {
                  iov.advance(n);
                }
                Some(Err(ref e))
                  if e.kind() == std::io::ErrorKind::WouldBlock =>
                {
                  break;
                }
                Some(Err(_)) => {
                  error = true;
                  break;
                }
              }
            }
          } else {
            loop {
              if pw.offset >= pw.data.len() {
                done = true;
                break;
              }
              match stream.try_write(&pw.data[pw.offset..]) {
                Ok(n) => {
                  pw.offset += n;
                }
                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
                  break;
                }
                Err(_) => {
                  error = true;
                  break;
                }
              }
            }
          }
          (done, error)
        };
        // Borrows on stream and pw dropped here.

        if done {
          let pw = (*tcp_ptr).internal_write_queue.pop_front().unwrap();
          any_work = true;
          completed_writes.push((pw.req, pw.cb, 0));
          count -= 1;
          if count > 0 {
            continue; // Try the next write in the queue.
          }
          break;
        } else if error {
          let pw = (*tcp_ptr).internal_write_queue.pop_front().unwrap();
          any_work = true;
          completed_writes.push((pw.req, pw.cb, UV_EPIPE));
          // Match libuv: stop writing after an error.
          break;
        } else {
          break; // WouldBlock -- retry next tick
        }
      }
    }
  }

  // Fire write callbacks after the write loop, matching libuv's
  // uv__write_callbacks(). No outstanding borrows on the TCP handle.
  unsafe {
    for (req, cb, status) in completed_writes {
      if let Some(cb) = cb {
        cb(req, status);
      }
    }
  }

  // 5. Complete deferred shutdown once write queue is drained.
  unsafe {
    if (*tcp_ptr).internal_write_queue.is_empty()
      && (*tcp_ptr).internal_shutdown.is_some()
      && (*tcp_ptr).internal_stream.is_some()
    {
      crate::uv_compat::stream::complete_shutdown(tcp_ptr, cx);
      any_work = true;
    }
  }

  // 6. Re-register tokio interest for the next edge.
  //
  // `poll_*_ready` stores a waker only when it returns Pending.
  // Under normal operation the read/write loops above hit
  // WouldBlock on their last iteration, which clears tokio's
  // internal readiness bit; the paired poll_*_ready here then
  // returns Pending and stores the waker, and we're good.
  //
  // The count==32 starvation break is an exception: it exits
  // mid-stream with readiness still armed and no waker. In that
  // case, poll_*_ready returns Ready (no waker stored) and we
  // mark_ready to re-queue the handle for another run_io pass.
  unsafe {
    if let Some(ref stream) = (*tcp_ptr).internal_stream {
      let mut needs_requeue = false;
      if (*tcp_ptr).internal_reading
        && matches!(stream.poll_read_ready(cx), Poll::Ready(_))
      {
        needs_requeue = true;
      }
      if !(*tcp_ptr).internal_write_queue.is_empty()
        && matches!(stream.poll_write_ready(cx), Poll::Ready(_))
      {
        needs_requeue = true;
      }
      if needs_requeue && let Some(w) = (*tcp_ptr).internal_waker.as_ref() {
        w.mark_ready();
      }
    }
  }

  any_work
}
