//! Host-side shadow-handle reconstruction for the native kboxlike backend.
//!
//! The fd model stores durable [`ShadowBacking`] metadata. This module turns
//! that metadata back into live supervisor-owned host fds during restore.

use std::collections::BTreeMap;
use std::fs::{self, OpenOptions};
use std::os::fd::{AsRawFd, FromRawFd, OwnedFd};
use std::path::{Component, Path, PathBuf};

#[cfg(target_os = "linux")]
use super::fd::KboxlikeFdSystem;
#[cfg(target_os = "linux")]
use super::fd::ModelThreadId;
use super::fd::{
    FdError, ShadowBacking, ShadowInstallPlan, ShadowKind, ShadowObject, ShadowRebuilder,
};
#[cfg(target_os = "linux")]
use super::snapshot::{
    KboxlikeEpollShadowBackingPlan, KboxlikeFdQueuedDataPlan, KboxlikeFdScmRightsPlan,
    KboxlikeFdSocketOptionsPlan, KboxlikeFdSocketShutdownPlan, KboxlikeUnixCredentials,
};

#[cfg(target_os = "linux")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub(crate) struct KboxlikeFdKernelReplaySummary {
    pub(crate) epoll_interests: usize,
    pub(crate) socket_options: usize,
    pub(crate) queued_bytes: usize,
    pub(crate) socket_shutdowns: usize,
    pub(crate) scm_rights_messages: usize,
}

#[derive(Debug)]
pub(crate) struct HostShadowRebuilder {
    rootfs: PathBuf,
    handles: BTreeMap<i32, OwnedFd>,
    pending_pipe_endpoints: BTreeMap<String, OwnedFd>,
    pending_socketpair_endpoints: BTreeMap<String, OwnedFd>,
}

impl HostShadowRebuilder {
    pub(crate) fn new(rootfs: impl Into<PathBuf>) -> Self {
        Self {
            rootfs: rootfs.into(),
            handles: BTreeMap::new(),
            pending_pipe_endpoints: BTreeMap::new(),
            pending_socketpair_endpoints: BTreeMap::new(),
        }
    }

    pub(crate) fn handle_count(&self) -> usize {
        self.handles.len()
    }

    pub(crate) fn dup_handle(&self, supervisor_fd: i32) -> Result<OwnedFd, FdError> {
        if !self.handles.contains_key(&supervisor_fd) {
            return Err(FdError::BadFd(supervisor_fd));
        }
        dup_fd(supervisor_fd)
    }

    pub(crate) fn install_shadow(&self, plan: ShadowInstallPlan) -> Result<OwnedFd, FdError> {
        self.dup_handle_to(plan.shadow.supervisor_fd, plan.target_fd, plan.cloexec)
    }

    pub(crate) fn dup_handle_to(
        &self,
        supervisor_fd: i32,
        target_fd: i32,
        cloexec: bool,
    ) -> Result<OwnedFd, FdError> {
        if target_fd < 0 {
            return Err(FdError::InvalidFd(target_fd));
        }
        if !self.handles.contains_key(&supervisor_fd) {
            return Err(FdError::BadFd(supervisor_fd));
        }
        if supervisor_fd == target_fd {
            return Err(FdError::ShadowRebuildFailed(
                "local install target aliases supervisor fd",
            ));
        }
        dup_fd_to(supervisor_fd, target_fd, cloexec)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_epoll_interests(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeEpollShadowBackingPlan],
    ) -> Result<usize, FdError> {
        let mut replayed = 0;
        for plan in plans {
            let epoll_shadow = fd_system
                .descriptor(plan.fd_plan.model_pid, plan.fd_plan.fd)?
                .shadow
                .ok_or(FdError::NoBackingFd(plan.fd_plan.fd))?;
            self.require_live_handle(epoll_shadow.supervisor_fd)?;

            for interest in &plan.interests {
                let watched_shadow = fd_system
                    .descriptor(plan.fd_plan.model_pid, interest.target_fd)?
                    .shadow
                    .ok_or(FdError::NoBackingFd(interest.target_fd))?;
                self.require_live_handle(watched_shadow.supervisor_fd)?;

                let mut event = libc::epoll_event {
                    events: interest.events,
                    u64: interest.data,
                };
                let rc = unsafe {
                    libc::epoll_ctl(
                        epoll_shadow.supervisor_fd,
                        libc::EPOLL_CTL_ADD,
                        watched_shadow.supervisor_fd,
                        &mut event,
                    )
                };
                if rc < 0 {
                    return Err(FdError::ShadowRebuildFailed(
                        "failed to replay epoll interest",
                    ));
                }
                replayed += 1;
            }
        }
        Ok(replayed)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_queued_data(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeFdQueuedDataPlan],
    ) -> Result<usize, FdError> {
        let mut replayed_bytes = 0;
        for plan in plans {
            let injector_shadow = fd_system
                .descriptor(plan.model_pid, plan.injector_fd)?
                .shadow
                .ok_or(FdError::NoBackingFd(plan.injector_fd))?;
            self.require_live_handle(injector_shadow.supervisor_fd)?;
            write_all_fd(injector_shadow.supervisor_fd, &plan.bytes)?;
            replayed_bytes += plan.bytes.len();
        }
        Ok(replayed_bytes)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_socket_options(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeFdSocketOptionsPlan],
    ) -> Result<usize, FdError> {
        let mut replayed = 0;
        for plan in plans {
            let shadow = fd_system
                .descriptor(plan.model_pid, plan.fd)?
                .shadow
                .ok_or(FdError::NoBackingFd(plan.fd))?;
            self.require_live_handle(shadow.supervisor_fd)?;
            for option in &plan.int_options {
                set_socket_int_option(
                    shadow.supervisor_fd,
                    option.level,
                    option.name,
                    option.value,
                )?;
                replayed += 1;
            }
        }
        Ok(replayed)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_socket_shutdown(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeFdSocketShutdownPlan],
    ) -> Result<usize, FdError> {
        let mut replayed = 0;
        for plan in plans {
            let shadow = fd_system
                .descriptor(plan.model_pid, plan.fd)?
                .shadow
                .ok_or(FdError::NoBackingFd(plan.fd))?;
            self.require_live_handle(shadow.supervisor_fd)?;
            let how = match (plan.shutdown.read_closed, plan.shutdown.write_closed) {
                (true, true) => libc::SHUT_RDWR,
                (true, false) => libc::SHUT_RD,
                (false, true) => libc::SHUT_WR,
                (false, false) => continue,
            };
            if unsafe { libc::shutdown(shadow.supervisor_fd, how) } < 0 {
                return Err(FdError::ShadowRebuildFailed(
                    "failed to replay socket shutdown",
                ));
            }
            replayed += 1;
        }
        Ok(replayed)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_scm_rights(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeFdScmRightsPlan],
    ) -> Result<usize, FdError> {
        self.replay_fd_scm_rights_with_replacement_pids(fd_system, plans, &BTreeMap::new())
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_scm_rights_with_replacement_pids(
        &self,
        fd_system: &KboxlikeFdSystem,
        plans: &[KboxlikeFdScmRightsPlan],
        replacement_host_pids: &BTreeMap<ModelThreadId, i32>,
    ) -> Result<usize, FdError> {
        let mut replayed = 0;
        for plan in plans {
            let injector_shadow = fd_system
                .descriptor(plan.model_pid, plan.injector_fd)?
                .shadow
                .ok_or(FdError::NoBackingFd(plan.injector_fd))?;
            self.require_live_handle(injector_shadow.supervisor_fd)?;
            let mut passed_handles = Vec::with_capacity(plan.passed_fds.len());
            for passed_fd in &plan.passed_fds {
                let passed_shadow = fd_system
                    .descriptor(plan.model_pid, *passed_fd)?
                    .shadow
                    .ok_or(FdError::NoBackingFd(*passed_fd))?;
                self.require_live_handle(passed_shadow.supervisor_fd)?;
                passed_handles.push(self.dup_handle(passed_shadow.supervisor_fd)?);
            }
            let credentials = remap_scm_credentials(plan, replacement_host_pids)?;
            send_scm_rights_message(
                injector_shadow.supervisor_fd,
                &plan.data,
                &passed_handles,
                credentials.as_ref(),
            )?;
            replayed += 1;
        }
        Ok(replayed)
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_kernel_state(
        &self,
        fd_system: &KboxlikeFdSystem,
        epoll_plans: &[KboxlikeEpollShadowBackingPlan],
        socket_options_plans: &[KboxlikeFdSocketOptionsPlan],
        queued_data_plans: &[KboxlikeFdQueuedDataPlan],
        socket_shutdown_plans: &[KboxlikeFdSocketShutdownPlan],
        scm_rights_plans: &[KboxlikeFdScmRightsPlan],
    ) -> Result<KboxlikeFdKernelReplaySummary, FdError> {
        self.replay_fd_kernel_state_with_replacement_pids(
            fd_system,
            epoll_plans,
            socket_options_plans,
            queued_data_plans,
            socket_shutdown_plans,
            scm_rights_plans,
            &BTreeMap::new(),
        )
    }

    #[cfg(target_os = "linux")]
    pub(crate) fn replay_fd_kernel_state_with_replacement_pids(
        &self,
        fd_system: &KboxlikeFdSystem,
        epoll_plans: &[KboxlikeEpollShadowBackingPlan],
        socket_options_plans: &[KboxlikeFdSocketOptionsPlan],
        queued_data_plans: &[KboxlikeFdQueuedDataPlan],
        socket_shutdown_plans: &[KboxlikeFdSocketShutdownPlan],
        scm_rights_plans: &[KboxlikeFdScmRightsPlan],
        replacement_host_pids: &BTreeMap<ModelThreadId, i32>,
    ) -> Result<KboxlikeFdKernelReplaySummary, FdError> {
        // Keep side-effectful stream restore ordered: options before SCM,
        // all socket data before shutdown, and SCM after replacement pid mapping.
        let epoll_interests = self.replay_epoll_interests(fd_system, epoll_plans)?;
        let socket_options = self.replay_fd_socket_options(fd_system, socket_options_plans)?;
        let queued_bytes = self.replay_fd_queued_data(fd_system, queued_data_plans)?;
        let scm_rights_messages = self.replay_fd_scm_rights_with_replacement_pids(
            fd_system,
            scm_rights_plans,
            replacement_host_pids,
        )?;
        let socket_shutdowns = self.replay_fd_socket_shutdown(fd_system, socket_shutdown_plans)?;
        Ok(KboxlikeFdKernelReplaySummary {
            epoll_interests,
            socket_options,
            queued_bytes,
            socket_shutdowns,
            scm_rights_messages,
        })
    }

    fn require_live_handle(&self, supervisor_fd: i32) -> Result<(), FdError> {
        if self.handles.contains_key(&supervisor_fd) {
            Ok(())
        } else {
            Err(FdError::BadFd(supervisor_fd))
        }
    }

    fn rebuild_guest_path(
        &mut self,
        kind: ShadowKind,
        path: &str,
        writable: bool,
    ) -> Result<ShadowObject, FdError> {
        let host_path = self.resolve_guest_path(path)?;
        let file = OpenOptions::new()
            .read(true)
            .write(writable)
            .open(host_path)
            .map_err(|_| FdError::ShadowRebuildFailed("failed to open guest-path shadow"))?;
        let fd: OwnedFd = file.into();
        Ok(self.insert_handle(kind, fd))
    }

    fn rebuild_host_path(
        &mut self,
        kind: ShadowKind,
        path: &str,
        writable: bool,
    ) -> Result<ShadowObject, FdError> {
        let file = OpenOptions::new()
            .read(true)
            .write(writable)
            .open(path)
            .map_err(|_| FdError::ShadowRebuildFailed("failed to open host-path shadow"))?;
        let fd: OwnedFd = file.into();
        Ok(self.insert_handle(kind, fd))
    }

    fn rebuild_host_passthrough(
        &mut self,
        kind: ShadowKind,
        label: &str,
    ) -> Result<ShadowObject, FdError> {
        match HostPassthroughSpec::parse(label)? {
            HostPassthroughSpec::EventFd { initval, flags } => {
                let fd = create_eventfd(initval, flags)?;
                Ok(self.insert_handle(kind, fd))
            }
            HostPassthroughSpec::Epoll { .. } => {
                let fd = create_epoll()?;
                Ok(self.insert_handle(kind, fd))
            }
            HostPassthroughSpec::TimerFd {
                clockid,
                flags,
                value_sec,
                value_nsec,
                interval_sec,
                interval_nsec,
            } => {
                let fd = create_timerfd(
                    clockid,
                    flags,
                    value_sec,
                    value_nsec,
                    interval_sec,
                    interval_nsec,
                )?;
                Ok(self.insert_handle(kind, fd))
            }
            HostPassthroughSpec::Pipe { group, endpoint } => {
                let key = endpoint_key(&group, endpoint);
                if let Some(fd) = self.pending_pipe_endpoints.remove(&key) {
                    return Ok(self.insert_handle(kind, fd));
                }

                let [read_end, write_end] = create_pipe()?;
                let (selected, pending, pending_endpoint) = if endpoint == 0 {
                    (read_end, write_end, 1)
                } else {
                    (write_end, read_end, 0)
                };
                self.pending_pipe_endpoints
                    .insert(endpoint_key(&group, pending_endpoint), pending);
                Ok(self.insert_handle(kind, selected))
            }
            HostPassthroughSpec::SocketPair { group, endpoint } => {
                let key = endpoint_key(&group, endpoint);
                if let Some(fd) = self.pending_socketpair_endpoints.remove(&key) {
                    return Ok(self.insert_handle(kind, fd));
                }

                let [a, b] = create_socketpair()?;
                let (selected, pending, pending_endpoint) =
                    if endpoint == 0 { (a, b, 1) } else { (b, a, 0) };
                self.pending_socketpair_endpoints
                    .insert(endpoint_key(&group, pending_endpoint), pending);
                Ok(self.insert_handle(kind, selected))
            }
            HostPassthroughSpec::LiveFd { pid, fd } => {
                let fd = duplicate_live_fd(pid, fd)?;
                Ok(self.insert_handle(kind, fd))
            }
        }
    }

    fn insert_handle(&mut self, kind: ShadowKind, fd: OwnedFd) -> ShadowObject {
        let supervisor_fd = fd.as_raw_fd();
        self.handles.insert(supervisor_fd, fd);
        ShadowObject {
            kind,
            supervisor_fd,
        }
    }

    fn resolve_guest_path(&self, path: &str) -> Result<PathBuf, FdError> {
        let guest_path = Path::new(path);
        if !guest_path.is_absolute() {
            return Err(FdError::ShadowRebuildFailed(
                "guest-path shadow backing must be absolute",
            ));
        }

        let mut joined = self.rootfs.clone();
        for component in guest_path.components() {
            match component {
                Component::RootDir | Component::CurDir => {}
                Component::Normal(part) => joined.push(part),
                Component::ParentDir | Component::Prefix(_) => {
                    return Err(FdError::ShadowRebuildFailed(
                        "guest-path shadow escapes rootfs",
                    ));
                }
            }
        }

        let root = fs::canonicalize(&self.rootfs)
            .map_err(|_| FdError::ShadowRebuildFailed("failed to canonicalize rootfs"))?;
        let resolved = fs::canonicalize(joined)
            .map_err(|_| FdError::ShadowRebuildFailed("failed to resolve guest-path shadow"))?;
        if !resolved.starts_with(root) {
            return Err(FdError::ShadowRebuildFailed(
                "guest-path shadow escapes rootfs",
            ));
        }
        Ok(resolved)
    }
}

#[cfg(target_os = "linux")]
fn remap_scm_credentials(
    plan: &KboxlikeFdScmRightsPlan,
    replacement_host_pids: &BTreeMap<ModelThreadId, i32>,
) -> Result<Option<KboxlikeUnixCredentials>, FdError> {
    let Some(mut credentials) = plan.credentials.clone() else {
        return Ok(None);
    };
    let Some(identity) = plan.credential_identity else {
        return Ok(Some(credentials));
    };
    if replacement_host_pids.is_empty() {
        return Ok(Some(credentials));
    }
    let Some(replacement_host_pid) = replacement_host_pids
        .get(&identity.model_thread_id)
        .copied()
    else {
        return Err(FdError::ShadowRebuildFailed(
            "missing replacement credential pid",
        ));
    };
    if replacement_host_pid <= 0 {
        return Err(FdError::ShadowRebuildFailed(
            "invalid replacement credential pid",
        ));
    }
    credentials.pid = replacement_host_pid;
    Ok(Some(credentials))
}

impl ShadowRebuilder for HostShadowRebuilder {
    fn rebuild_shadow(
        &mut self,
        kind: ShadowKind,
        backing: &ShadowBacking,
    ) -> Result<ShadowObject, FdError> {
        match backing {
            ShadowBacking::Ephemeral => Err(FdError::InvalidSnapshot(
                "ephemeral shadow cannot be rebuilt after restore",
            )),
            ShadowBacking::GuestPath { path, writable } => {
                self.rebuild_guest_path(kind, path, *writable)
            }
            ShadowBacking::HostPath { path, writable } => {
                self.rebuild_host_path(kind, path, *writable)
            }
            ShadowBacking::HostPassthrough { label } => self.rebuild_host_passthrough(kind, label),
        }
    }
}

#[derive(Debug, PartialEq, Eq)]
enum HostPassthroughSpec {
    EventFd {
        initval: u32,
        flags: i32,
    },
    Epoll {
        group: String,
    },
    TimerFd {
        clockid: i32,
        flags: i32,
        value_sec: i64,
        value_nsec: i64,
        interval_sec: i64,
        interval_nsec: i64,
    },
    Pipe {
        group: String,
        endpoint: u8,
    },
    SocketPair {
        group: String,
        endpoint: u8,
    },
    LiveFd {
        pid: i32,
        fd: i32,
    },
}

impl HostPassthroughSpec {
    fn parse(label: &str) -> Result<Self, FdError> {
        if let Some(rest) = label.strip_prefix("eventfd:") {
            return parse_eventfd_spec(rest);
        }
        if let Some(group) = label.strip_prefix("epoll:") {
            if group.is_empty() {
                return Err(FdError::ShadowRebuildFailed("invalid epoll shadow label"));
            }
            return Ok(HostPassthroughSpec::Epoll {
                group: group.to_string(),
            });
        }
        if let Some(rest) = label.strip_prefix("timerfd:") {
            return parse_timerfd_spec(rest);
        }
        if let Some(rest) = label.strip_prefix("pipe:") {
            let (group, endpoint) = parse_group_endpoint_spec(rest, "pipe")?;
            return Ok(HostPassthroughSpec::Pipe { group, endpoint });
        }
        if let Some(rest) = label.strip_prefix("socketpair:") {
            let (group, endpoint) = parse_group_endpoint_spec(rest, "socketpair")?;
            return Ok(HostPassthroughSpec::SocketPair { group, endpoint });
        }
        if let Some(rest) = label.strip_prefix("livefd:") {
            let (pid, fd) = parse_live_fd_spec(rest)?;
            return Ok(HostPassthroughSpec::LiveFd { pid, fd });
        }
        Err(FdError::ShadowRebuildUnsupported(
            "unsupported host-passthrough shadow label",
        ))
    }
}

fn parse_eventfd_spec(spec: &str) -> Result<HostPassthroughSpec, FdError> {
    let mut initval = 0u32;
    let mut flags = 0i32;
    if !spec.is_empty() {
        for field in spec.split(',') {
            let (key, value) = field
                .split_once('=')
                .ok_or(FdError::ShadowRebuildFailed("invalid eventfd shadow label"))?;
            match key {
                "init" => {
                    initval = value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid eventfd init value"))?;
                }
                "flags" => {
                    flags = value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid eventfd flags"))?;
                }
                _ => {
                    return Err(FdError::ShadowRebuildFailed("invalid eventfd shadow label"));
                }
            }
        }
    }
    Ok(HostPassthroughSpec::EventFd { initval, flags })
}

fn parse_timerfd_spec(spec: &str) -> Result<HostPassthroughSpec, FdError> {
    let mut clockid = None;
    let mut flags = None;
    let mut value_sec = None;
    let mut value_nsec = None;
    let mut interval_sec = None;
    let mut interval_nsec = None;
    for field in spec.split(',') {
        let (key, value) = field
            .split_once('=')
            .ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?;
        match key {
            "clockid" => {
                clockid = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd clockid"))?,
                );
            }
            "flags" => {
                flags = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd flags"))?,
                );
            }
            "value_sec" => {
                value_sec = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd value"))?,
                );
            }
            "value_nsec" => {
                value_nsec = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd value"))?,
                );
            }
            "interval_sec" => {
                interval_sec = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd interval"))?,
                );
            }
            "interval_nsec" => {
                interval_nsec = Some(
                    value
                        .parse()
                        .map_err(|_| FdError::ShadowRebuildFailed("invalid timerfd interval"))?,
                );
            }
            _ => {
                return Err(FdError::ShadowRebuildFailed("invalid timerfd shadow label"));
            }
        }
    }

    Ok(HostPassthroughSpec::TimerFd {
        clockid: clockid.ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
        flags: flags.ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
        value_sec: value_sec.ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
        value_nsec: value_nsec
            .ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
        interval_sec: interval_sec
            .ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
        interval_nsec: interval_nsec
            .ok_or(FdError::ShadowRebuildFailed("invalid timerfd shadow label"))?,
    })
}

fn parse_group_endpoint_spec(spec: &str, kind: &str) -> Result<(String, u8), FdError> {
    let invalid_label = match kind {
        "pipe" => "invalid pipe shadow label",
        "socketpair" => "invalid socketpair shadow label",
        _ => "invalid host-passthrough shadow label",
    };
    let invalid_endpoint = match kind {
        "pipe" => "invalid pipe endpoint",
        "socketpair" => "invalid socketpair endpoint",
        _ => "invalid host-passthrough endpoint",
    };
    let (group, endpoint) = spec
        .split_once(':')
        .ok_or(FdError::ShadowRebuildFailed(invalid_label))?;
    if group.is_empty() {
        return Err(FdError::ShadowRebuildFailed(invalid_label));
    }
    let endpoint = endpoint
        .parse::<u8>()
        .map_err(|_| FdError::ShadowRebuildFailed(invalid_endpoint))?;
    if endpoint > 1 {
        return Err(FdError::ShadowRebuildFailed(invalid_endpoint));
    }
    Ok((group.to_string(), endpoint))
}

fn parse_live_fd_spec(spec: &str) -> Result<(i32, i32), FdError> {
    let (pid_raw, fd_raw) = spec
        .split_once(':')
        .ok_or(FdError::ShadowRebuildFailed("invalid livefd shadow label"))?;
    let pid = pid_raw
        .parse::<i32>()
        .map_err(|_| FdError::ShadowRebuildFailed("invalid livefd pid"))?;
    let fd = fd_raw
        .parse::<i32>()
        .map_err(|_| FdError::ShadowRebuildFailed("invalid livefd fd"))?;
    if pid <= 0 || fd < 0 {
        return Err(FdError::ShadowRebuildFailed("invalid livefd values"));
    }
    Ok((pid, fd))
}

#[cfg(target_os = "linux")]
fn duplicate_live_fd(pid: i32, fd: i32) -> Result<OwnedFd, FdError> {
    let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, pid, 0) };
    if pidfd < 0 {
        return Err(FdError::ShadowRebuildFailed("pidfd_open failed"));
    }
    let pidfd = unsafe { OwnedFd::from_raw_fd(pidfd as i32) };
    let duplicated = unsafe {
        libc::syscall(
            libc::SYS_pidfd_getfd,
            pidfd.as_raw_fd(),
            fd,
            0 as libc::c_uint,
        )
    };
    if duplicated < 0 {
        return Err(FdError::ShadowRebuildFailed("pidfd_getfd failed"));
    }
    Ok(unsafe { OwnedFd::from_raw_fd(duplicated as i32) })
}

#[cfg(not(target_os = "linux"))]
fn duplicate_live_fd(_pid: i32, _fd: i32) -> Result<OwnedFd, FdError> {
    Err(FdError::ShadowRebuildUnsupported(
        "livefd host-passthrough requires linux",
    ))
}

fn endpoint_key(group: &str, endpoint: u8) -> String {
    format!("{group}:{endpoint}")
}

fn write_all_fd(fd: i32, mut bytes: &[u8]) -> Result<(), FdError> {
    while !bytes.is_empty() {
        let written =
            unsafe { libc::write(fd, bytes.as_ptr() as *const libc::c_void, bytes.len()) };
        if written < 0 {
            return Err(FdError::ShadowRebuildFailed(
                "failed to replay queued fd bytes",
            ));
        }
        if written == 0 {
            return Err(FdError::ShadowRebuildFailed(
                "zero-length queued fd replay write",
            ));
        }
        bytes = &bytes[written as usize..];
    }
    Ok(())
}

#[cfg(target_os = "linux")]
fn send_scm_rights_message(
    fd: i32,
    data: &[u8],
    passed: &[OwnedFd],
    credentials: Option<&KboxlikeUnixCredentials>,
) -> Result<(), FdError> {
    if data.is_empty() || passed.is_empty() {
        return Err(FdError::ShadowRebuildFailed("invalid SCM_RIGHTS replay"));
    }
    let mut data = data.to_vec();
    let mut iov = libc::iovec {
        iov_base: data.as_mut_ptr() as *mut libc::c_void,
        iov_len: data.len(),
    };
    let fd_bytes = passed
        .len()
        .checked_mul(std::mem::size_of::<libc::c_int>())
        .ok_or(FdError::ShadowRebuildFailed("too many SCM_RIGHTS fds"))?;
    let credentials_len = credentials
        .map(|_| unsafe {
            libc::CMSG_SPACE(std::mem::size_of::<libc::ucred>() as libc::c_uint) as usize
        })
        .unwrap_or(0);
    let control_len = unsafe { libc::CMSG_SPACE(fd_bytes as libc::c_uint) as usize }
        .checked_add(credentials_len)
        .ok_or(FdError::ShadowRebuildFailed("too many control bytes"))?;
    let mut control = vec![0u8; control_len];
    let msg = libc::msghdr {
        msg_name: std::ptr::null_mut(),
        msg_namelen: 0,
        msg_iov: &mut iov,
        msg_iovlen: 1,
        msg_control: control.as_mut_ptr() as *mut libc::c_void,
        msg_controllen: control.len(),
        msg_flags: 0,
    };

    let cmsg = unsafe { libc::CMSG_FIRSTHDR(&msg) };
    if cmsg.is_null() {
        return Err(FdError::ShadowRebuildFailed("missing SCM_RIGHTS header"));
    }
    unsafe {
        (*cmsg).cmsg_level = libc::SOL_SOCKET;
        (*cmsg).cmsg_type = libc::SCM_RIGHTS;
        (*cmsg).cmsg_len = libc::CMSG_LEN(fd_bytes as libc::c_uint) as _;
        let data_ptr = libc::CMSG_DATA(cmsg) as *mut libc::c_int;
        for (index, passed_fd) in passed.iter().enumerate() {
            data_ptr.add(index).write_unaligned(passed_fd.as_raw_fd());
        }
    }

    if let Some(credentials) = credentials {
        let cmsg = unsafe { libc::CMSG_NXTHDR(&msg, cmsg) };
        if cmsg.is_null() {
            return Err(FdError::ShadowRebuildFailed(
                "missing SCM_CREDENTIALS header",
            ));
        }
        unsafe {
            (*cmsg).cmsg_level = libc::SOL_SOCKET;
            (*cmsg).cmsg_type = libc::SCM_CREDENTIALS;
            (*cmsg).cmsg_len =
                libc::CMSG_LEN(std::mem::size_of::<libc::ucred>() as libc::c_uint) as _;
            let creds = libc::ucred {
                pid: credentials.pid,
                uid: credentials.uid,
                gid: credentials.gid,
            };
            (libc::CMSG_DATA(cmsg) as *mut libc::ucred).write_unaligned(creds);
        }
    }

    let written = unsafe { libc::sendmsg(fd, &msg, libc::MSG_NOSIGNAL) };
    if written != data.len() as isize {
        return Err(FdError::ShadowRebuildFailed(
            "failed to replay SCM_RIGHTS message",
        ));
    }
    Ok(())
}

#[cfg(target_os = "linux")]
fn set_socket_int_option(fd: i32, level: i32, name: i32, value: i32) -> Result<(), FdError> {
    let value = value as libc::c_int;
    let rc = unsafe {
        libc::setsockopt(
            fd,
            level,
            name,
            &value as *const libc::c_int as *const libc::c_void,
            std::mem::size_of::<libc::c_int>() as libc::socklen_t,
        )
    };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed(
            "failed to replay socket option",
        ));
    }
    Ok(())
}

#[cfg(target_os = "linux")]
fn get_socket_int_option(fd: i32, level: i32, name: i32) -> Result<i32, FdError> {
    let mut value = 0 as libc::c_int;
    let mut len = std::mem::size_of::<libc::c_int>() as libc::socklen_t;
    let rc = unsafe {
        libc::getsockopt(
            fd,
            level,
            name,
            &mut value as *mut libc::c_int as *mut libc::c_void,
            &mut len,
        )
    };
    if rc < 0 || len as usize != std::mem::size_of::<libc::c_int>() {
        return Err(FdError::ShadowRebuildFailed("failed to read socket option"));
    }
    Ok(value)
}

fn dup_fd(fd: i32) -> Result<OwnedFd, FdError> {
    let duplicated = unsafe { libc::dup(fd) };
    if duplicated < 0 {
        return Err(FdError::ShadowRebuildFailed(
            "failed to duplicate shadow fd",
        ));
    }
    Ok(unsafe { OwnedFd::from_raw_fd(duplicated) })
}

fn dup_fd_to(source_fd: i32, target_fd: i32, cloexec: bool) -> Result<OwnedFd, FdError> {
    let installed = unsafe { libc::dup2(source_fd, target_fd) };
    if installed < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to install shadow fd"));
    }
    set_cloexec_state(installed, cloexec)?;
    Ok(unsafe { OwnedFd::from_raw_fd(installed) })
}

#[cfg(target_os = "linux")]
fn create_eventfd(initval: u32, flags: i32) -> Result<OwnedFd, FdError> {
    let fd = unsafe { libc::eventfd(initval, flags) };
    if fd < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create eventfd"));
    }
    Ok(unsafe { OwnedFd::from_raw_fd(fd) })
}

#[cfg(not(target_os = "linux"))]
fn create_eventfd(_initval: u32, _flags: i32) -> Result<OwnedFd, FdError> {
    Err(FdError::ShadowRebuildUnsupported(
        "eventfd host-passthrough requires linux",
    ))
}

#[cfg(target_os = "linux")]
fn create_epoll() -> Result<OwnedFd, FdError> {
    let fd = unsafe { libc::epoll_create1(libc::EPOLL_CLOEXEC) };
    if fd < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create epoll fd"));
    }
    Ok(unsafe { OwnedFd::from_raw_fd(fd) })
}

#[cfg(not(target_os = "linux"))]
fn create_epoll() -> Result<OwnedFd, FdError> {
    Err(FdError::ShadowRebuildUnsupported(
        "epoll host-passthrough requires linux",
    ))
}

#[cfg(target_os = "linux")]
fn create_timerfd(
    clockid: i32,
    flags: i32,
    value_sec: i64,
    value_nsec: i64,
    interval_sec: i64,
    interval_nsec: i64,
) -> Result<OwnedFd, FdError> {
    if !(0..1_000_000_000).contains(&value_nsec) || !(0..1_000_000_000).contains(&interval_nsec) {
        return Err(FdError::ShadowRebuildFailed("invalid timerfd timespec"));
    }
    let fd = unsafe { libc::timerfd_create(clockid, flags) };
    if fd < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create timerfd"));
    }
    let owned = unsafe { OwnedFd::from_raw_fd(fd) };
    let spec = libc::itimerspec {
        it_interval: libc::timespec {
            tv_sec: interval_sec as libc::time_t,
            tv_nsec: interval_nsec as libc::c_long,
        },
        it_value: libc::timespec {
            tv_sec: value_sec as libc::time_t,
            tv_nsec: value_nsec as libc::c_long,
        },
    };
    let rc = unsafe { libc::timerfd_settime(owned.as_raw_fd(), 0, &spec, std::ptr::null_mut()) };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to arm timerfd"));
    }
    Ok(owned)
}

#[cfg(not(target_os = "linux"))]
fn create_timerfd(
    _clockid: i32,
    _flags: i32,
    _value_sec: i64,
    _value_nsec: i64,
    _interval_sec: i64,
    _interval_nsec: i64,
) -> Result<OwnedFd, FdError> {
    Err(FdError::ShadowRebuildUnsupported(
        "timerfd host-passthrough requires linux",
    ))
}

#[cfg(target_os = "linux")]
fn create_pipe() -> Result<[OwnedFd; 2], FdError> {
    let mut fds = [-1; 2];
    let rc = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create pipe"));
    }
    Ok(unsafe { [OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])] })
}

#[cfg(not(target_os = "linux"))]
fn create_pipe() -> Result<[OwnedFd; 2], FdError> {
    let mut fds = [-1; 2];
    let rc = unsafe { libc::pipe(fds.as_mut_ptr()) };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create pipe"));
    }
    set_cloexec_state(fds[0], true)?;
    set_cloexec_state(fds[1], true)?;
    Ok(unsafe { [OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])] })
}

fn create_socketpair() -> Result<[OwnedFd; 2], FdError> {
    let mut fds = [-1; 2];
    let rc = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to create socketpair"));
    }
    set_cloexec_state(fds[0], true)?;
    set_cloexec_state(fds[1], true)?;
    Ok(unsafe { [OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])] })
}

fn set_cloexec_state(fd: i32, cloexec: bool) -> Result<(), FdError> {
    let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
    if flags < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to read fd flags"));
    }
    let new_flags = if cloexec {
        flags | libc::FD_CLOEXEC
    } else {
        flags & !libc::FD_CLOEXEC
    };
    let rc = unsafe { libc::fcntl(fd, libc::F_SETFD, new_flags) };
    if rc < 0 {
        return Err(FdError::ShadowRebuildFailed("failed to set fd cloexec"));
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    #[cfg(target_os = "linux")]
    use crate::kboxlike::dispatch::KboxlikeTraceeIdentity;
    #[cfg(target_os = "linux")]
    use crate::kboxlike::fd::KboxlikeSocketShutdownState;
    use crate::kboxlike::fd::{KboxlikeFdSystem, ShadowInstallPlan};
    #[cfg(target_os = "linux")]
    use crate::kboxlike::snapshot::{
        KboxlikeEpollInterestBackingPlan, KboxlikeEpollShadowBackingPlan, KboxlikeFdQueuedDataPlan,
        KboxlikeFdScmRightsPlan, KboxlikeFdShadowBackingPlan, KboxlikeFdSocketOptionsPlan,
        KboxlikeFdSocketShutdownPlan, KboxlikeSocketIntOption, KboxlikeUnixCredentials,
    };
    use std::fs::File;
    use std::io::{Read, Write};
    use std::os::fd::{AsRawFd, IntoRawFd};

    fn test_rootfs(name: &str) -> PathBuf {
        let mut path = std::env::temp_dir();
        path.push(format!(
            "supermachine-kboxlike-shadow-{name}-{}",
            std::process::id()
        ));
        let _ = fs::remove_dir_all(&path);
        fs::create_dir_all(&path).unwrap();
        path
    }

    fn read_owned_fd(fd: OwnedFd) -> String {
        let mut file = File::from(fd);
        let mut out = String::new();
        file.read_to_string(&mut out).unwrap();
        out
    }

    fn placeholder_fd(rootfs: &Path, name: &str) -> i32 {
        let path = rootfs.join(name);
        fs::write(&path, b"placeholder").unwrap();
        File::open(path).unwrap().into_raw_fd()
    }

    fn fd_cloexec(fd: i32) -> bool {
        let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
        assert!(flags >= 0);
        flags & libc::FD_CLOEXEC != 0
    }

    #[cfg(target_os = "linux")]
    fn recv_one_scm_right(
        fd: i32,
        len: usize,
    ) -> (Vec<u8>, OwnedFd, Option<KboxlikeUnixCredentials>) {
        let mut data = vec![0u8; len];
        let mut iov = libc::iovec {
            iov_base: data.as_mut_ptr() as *mut libc::c_void,
            iov_len: data.len(),
        };
        let mut control = vec![
            0u8;
            unsafe {
                libc::CMSG_SPACE(std::mem::size_of::<libc::c_int>() as u32)
                    + libc::CMSG_SPACE(std::mem::size_of::<libc::ucred>() as u32)
            } as usize
        ];
        let mut msg = libc::msghdr {
            msg_name: std::ptr::null_mut(),
            msg_namelen: 0,
            msg_iov: &mut iov,
            msg_iovlen: 1,
            msg_control: control.as_mut_ptr() as *mut libc::c_void,
            msg_controllen: control.len(),
            msg_flags: 0,
        };
        let read = unsafe { libc::recvmsg(fd, &mut msg, 0) };
        assert_eq!(read, len as isize);
        data.truncate(read as usize);
        let mut passed = None;
        let mut credentials = None;
        let mut cmsg = unsafe { libc::CMSG_FIRSTHDR(&msg) };
        while !cmsg.is_null() {
            let header = unsafe { &*cmsg };
            if header.cmsg_level == libc::SOL_SOCKET && header.cmsg_type == libc::SCM_RIGHTS {
                passed =
                    Some(unsafe { (libc::CMSG_DATA(cmsg) as *const libc::c_int).read_unaligned() });
            } else if header.cmsg_level == libc::SOL_SOCKET
                && header.cmsg_type == libc::SCM_CREDENTIALS
            {
                let creds =
                    unsafe { (libc::CMSG_DATA(cmsg) as *const libc::ucred).read_unaligned() };
                credentials = Some(KboxlikeUnixCredentials {
                    pid: creds.pid,
                    uid: creds.uid,
                    gid: creds.gid,
                });
            }
            cmsg = unsafe { libc::CMSG_NXTHDR(&msg, cmsg) };
        }
        let passed = passed.expect("missing SCM_RIGHTS cmsg");
        assert!(passed >= 0);
        (data, unsafe { OwnedFd::from_raw_fd(passed) }, credentials)
    }

    #[test]
    fn guest_path_rebuilder_opens_confined_rootfs_file() {
        let rootfs = test_rootfs("guest-path");
        let lib = rootfs.join("usr/lib");
        fs::create_dir_all(&lib).unwrap();
        fs::write(lib.join("libstdc++.so.6"), b"shadow-bytes").unwrap();

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/usr/lib/libstdc++.so.6".to_string(),
                    writable: false,
                },
            )
            .unwrap();

        assert_eq!(shadow.kind, ShadowKind::LocalOnly);
        assert_eq!(rebuilder.handle_count(), 1);
        let dup = rebuilder.dup_handle(shadow.supervisor_fd).unwrap();
        assert_eq!(read_owned_fd(dup), "shadow-bytes");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn install_shadow_replaces_target_fd_with_rebuilt_handle() {
        let rootfs = test_rootfs("install-shadow");
        let lib = rootfs.join("usr/lib");
        fs::create_dir_all(&lib).unwrap();
        fs::write(lib.join("libstdc++.so.6"), b"installed-shadow").unwrap();

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/usr/lib/libstdc++.so.6".to_string(),
                    writable: false,
                },
            )
            .unwrap();
        let target_fd = placeholder_fd(&rootfs, "placeholder");

        let installed = rebuilder
            .install_shadow(ShadowInstallPlan {
                source_fd: 4,
                target_fd,
                shadow,
                cloexec: false,
            })
            .unwrap();

        assert_eq!(installed.as_raw_fd(), target_fd);
        assert!(!fd_cloexec(target_fd));
        assert_eq!(read_owned_fd(installed), "installed-shadow");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn install_shadow_honors_cloexec() {
        let rootfs = test_rootfs("install-cloexec");
        let lib = rootfs.join("usr/lib");
        fs::create_dir_all(&lib).unwrap();
        fs::write(lib.join("libv8.so"), b"cloexec-shadow").unwrap();

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/usr/lib/libv8.so".to_string(),
                    writable: false,
                },
            )
            .unwrap();
        let target_fd = placeholder_fd(&rootfs, "placeholder");

        let installed = rebuilder
            .install_shadow(ShadowInstallPlan {
                source_fd: 33033,
                target_fd,
                shadow,
                cloexec: true,
            })
            .unwrap();

        assert_eq!(installed.as_raw_fd(), target_fd);
        assert!(fd_cloexec(target_fd));
        drop(installed);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn install_shadow_rejects_unknown_supervisor_handle() {
        let rootfs = test_rootfs("install-missing");
        let rebuilder = HostShadowRebuilder::new(&rootfs);

        let err = rebuilder
            .install_shadow(ShadowInstallPlan {
                source_fd: 4,
                target_fd: 99_999,
                shadow: ShadowObject {
                    kind: ShadowKind::LocalOnly,
                    supervisor_fd: 88_888,
                },
                cloexec: false,
            })
            .unwrap_err();
        assert_eq!(err, FdError::BadFd(88_888));

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn local_install_rejects_target_that_aliases_supervisor_handle() {
        let rootfs = test_rootfs("install-alias");
        let lib = rootfs.join("usr/lib");
        fs::create_dir_all(&lib).unwrap();
        fs::write(lib.join("libalias.so"), b"alias-shadow").unwrap();

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/usr/lib/libalias.so".to_string(),
                    writable: false,
                },
            )
            .unwrap();

        let err = rebuilder
            .dup_handle_to(shadow.supervisor_fd, shadow.supervisor_fd, false)
            .unwrap_err();
        assert_eq!(
            err,
            FdError::ShadowRebuildFailed("local install target aliases supervisor fd")
        );

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn fd_snapshot_restore_uses_host_shadow_rebuilder() {
        let rootfs = test_rootfs("snapshot-restore");
        let lib = rootfs.join("usr/lib");
        fs::create_dir_all(&lib).unwrap();
        fs::write(lib.join("libv8_snapshot.so"), b"rebuilt-shadow").unwrap();

        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/usr/local/bin/node");
        fds.insert_shadow_fd_with_backing(
            pid,
            4,
            Some(44),
            ShadowObject {
                kind: ShadowKind::LocalOnly,
                supervisor_fd: 123,
            },
            ShadowBacking::GuestPath {
                path: "/usr/lib/libv8_snapshot.so".to_string(),
                writable: false,
            },
            false,
        )
        .unwrap();

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let restored =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        let rebuilt = restored.descriptor(pid, 4).unwrap().shadow.unwrap();

        assert_eq!(rebuilt.kind, ShadowKind::LocalOnly);
        assert_ne!(rebuilt.supervisor_fd, 123);
        let dup = rebuilder.dup_handle(rebuilt.supervisor_fd).unwrap();
        assert_eq!(read_owned_fd(dup), "rebuilt-shadow");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn guest_path_rebuilder_rejects_parent_escape() {
        let rootfs = test_rootfs("parent-escape");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);

        assert_eq!(
            rebuilder.rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/../etc/passwd".to_string(),
                    writable: false,
                },
            ),
            Err(FdError::ShadowRebuildFailed(
                "guest-path shadow escapes rootfs"
            ))
        );

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(unix)]
    #[test]
    fn guest_path_rebuilder_rejects_symlink_escape() {
        let rootfs = test_rootfs("symlink-escape");
        let outside = test_rootfs("symlink-outside");
        fs::write(outside.join("secret"), b"host-secret").unwrap();
        std::os::unix::fs::symlink(outside.join("secret"), rootfs.join("secret-link")).unwrap();
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);

        assert_eq!(
            rebuilder.rebuild_shadow(
                ShadowKind::LocalOnly,
                &ShadowBacking::GuestPath {
                    path: "/secret-link".to_string(),
                    writable: false,
                },
            ),
            Err(FdError::ShadowRebuildFailed(
                "guest-path shadow escapes rootfs"
            ))
        );

        fs::remove_dir_all(rootfs).unwrap();
        fs::remove_dir_all(outside).unwrap();
    }

    #[test]
    fn host_passthrough_rebuilder_recreates_socketpair_endpoints() {
        let rootfs = test_rootfs("socketpair");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);

        let a = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "socketpair:crashpad:0".to_string(),
                },
            )
            .unwrap();
        let b = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "socketpair:crashpad:1".to_string(),
                },
            )
            .unwrap();

        let mut a_file = File::from(rebuilder.dup_handle(a.supervisor_fd).unwrap());
        let mut b_file = File::from(rebuilder.dup_handle(b.supervisor_fd).unwrap());
        a_file.write_all(b"ping").unwrap();
        let mut buf = [0u8; 4];
        b_file.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"ping");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn host_passthrough_rebuilder_recreates_pipe_endpoints() {
        let rootfs = test_rootfs("pipe");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);

        let read_end = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "pipe:network:0".to_string(),
                },
            )
            .unwrap();
        let write_end = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "pipe:network:1".to_string(),
                },
            )
            .unwrap();

        let mut reader = File::from(rebuilder.dup_handle(read_end.supervisor_fd).unwrap());
        let mut writer = File::from(rebuilder.dup_handle(write_end.supervisor_fd).unwrap());
        writer.write_all(b"pipe").unwrap();
        let mut buf = [0u8; 4];
        reader.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"pipe");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[test]
    fn parses_host_passthrough_labels() {
        assert_eq!(
            HostPassthroughSpec::parse("eventfd:init=7,flags=0").unwrap(),
            HostPassthroughSpec::EventFd {
                initval: 7,
                flags: 0
            }
        );
        assert_eq!(
            HostPassthroughSpec::parse("epoll:browser").unwrap(),
            HostPassthroughSpec::Epoll {
                group: "browser".to_string(),
            }
        );
        assert_eq!(
            HostPassthroughSpec::parse(
                "timerfd:clockid=1,flags=2048,value_sec=0,value_nsec=1000000,interval_sec=2,interval_nsec=3"
            )
            .unwrap(),
            HostPassthroughSpec::TimerFd {
                clockid: 1,
                flags: 2048,
                value_sec: 0,
                value_nsec: 1_000_000,
                interval_sec: 2,
                interval_nsec: 3,
            }
        );
        assert_eq!(
            HostPassthroughSpec::parse("pipe:network:0").unwrap(),
            HostPassthroughSpec::Pipe {
                group: "network".to_string(),
                endpoint: 0
            }
        );
        assert_eq!(
            HostPassthroughSpec::parse("socketpair:crashpad:1").unwrap(),
            HostPassthroughSpec::SocketPair {
                group: "crashpad".to_string(),
                endpoint: 1
            }
        );
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn host_passthrough_rebuilder_recreates_eventfd() {
        let rootfs = test_rootfs("eventfd");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "eventfd:init=5,flags=0".to_string(),
                },
            )
            .unwrap();

        let raw = rebuilder.dup_handle(shadow.supervisor_fd).unwrap();
        let mut value = 0u64;
        let rc = unsafe {
            libc::read(
                raw.as_raw_fd(),
                &mut value as *mut u64 as *mut libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);
        assert_eq!(value, 5);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn host_passthrough_rebuilder_recreates_epoll_fd() {
        let rootfs = test_rootfs("epoll");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label: "epoll:browser".to_string(),
                },
            )
            .unwrap();

        let raw = rebuilder.dup_handle(shadow.supervisor_fd).unwrap();
        let fd_path = fs::read_link(format!("/proc/self/fd/{}", raw.as_raw_fd())).unwrap();
        assert_eq!(fd_path.to_string_lossy(), "anon_inode:[eventpoll]");

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn host_passthrough_rebuilder_recreates_armed_timerfd() {
        let rootfs = test_rootfs("timerfd");
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let shadow = rebuilder
            .rebuild_shadow(
                ShadowKind::HostPassthrough,
                &ShadowBacking::HostPassthrough {
                    label:
                        "timerfd:clockid=1,flags=2048,value_sec=0,value_nsec=1000000,interval_sec=0,interval_nsec=0"
                            .to_string(),
                },
            )
            .unwrap();

        let raw = rebuilder.dup_handle(shadow.supervisor_fd).unwrap();
        let mut pollfd = libc::pollfd {
            fd: raw.as_raw_fd(),
            events: libc::POLLIN,
            revents: 0,
        };
        let ready = unsafe { libc::poll(&mut pollfd, 1, 500) };
        assert_eq!(ready, 1);
        let mut expirations = 0u64;
        let rc = unsafe {
            libc::read(
                raw.as_raw_fd(),
                &mut expirations as *mut u64 as *mut libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);
        assert!(expirations >= 1);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_epoll_interests_restores_eventfd_readiness() {
        let rootfs = test_rootfs("epoll-replay");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let eventfd_backing = ShadowBacking::HostPassthrough {
            label: "eventfd:init=0,flags=0".to_string(),
        };
        let epoll_backing = ShadowBacking::HostPassthrough {
            label: "epoll:browser".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            8,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 8,
            },
            eventfd_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            9,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 9,
            },
            epoll_backing.clone(),
            false,
        )
        .unwrap();

        let epoll_plan = KboxlikeEpollShadowBackingPlan {
            fd_plan: KboxlikeFdShadowBackingPlan {
                host_pid: 2001,
                model_pid: pid,
                model_thread_id: 1,
                fd: 9,
                target: "anon_inode:[eventpoll]".to_string(),
                cloexec: false,
                backing: epoll_backing,
            },
            interests: vec![KboxlikeEpollInterestBackingPlan {
                target_fd: 8,
                events: libc::EPOLLIN as u32,
                data: 0xfeed_cafe,
                target: Some("anon_inode:[eventfd]".to_string()),
                target_kind: Some(crate::kboxlike::snapshot::KboxlikeFdTargetKind::EventFd),
                target_backing: Some(eventfd_backing),
            }],
        };

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        assert_eq!(
            rebuilder
                .replay_epoll_interests(&rebuilt, &[epoll_plan])
                .unwrap(),
            1
        );

        let event_shadow = rebuilt.descriptor(pid, 8).unwrap().shadow.unwrap();
        let epoll_shadow = rebuilt.descriptor(pid, 9).unwrap().shadow.unwrap();
        let event_handle = rebuilder.dup_handle(event_shadow.supervisor_fd).unwrap();
        let value = 1u64;
        let rc = unsafe {
            libc::write(
                event_handle.as_raw_fd(),
                &value as *const u64 as *const libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);

        let epoll_handle = rebuilder.dup_handle(epoll_shadow.supervisor_fd).unwrap();
        let mut events = [libc::epoll_event { events: 0, u64: 0 }; 1];
        let ready =
            unsafe { libc::epoll_wait(epoll_handle.as_raw_fd(), events.as_mut_ptr(), 1, 0) };
        assert_eq!(ready, 1);
        let event_data = unsafe { std::ptr::addr_of!(events[0].u64).read_unaligned() };
        let event_flags = unsafe { std::ptr::addr_of!(events[0].events).read_unaligned() };
        assert_eq!(event_data, 0xfeed_cafe);
        assert_ne!(event_flags & libc::EPOLLIN as u32, 0);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_kernel_state_applies_ordered_restore_sequence() {
        let rootfs = test_rootfs("kernel-replay-sequence");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let queue_a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:queue:0".to_string(),
        };
        let queue_b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:queue:1".to_string(),
        };
        let scm_a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker:0".to_string(),
        };
        let scm_b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker:1".to_string(),
        };
        let eventfd_backing = ShadowBacking::HostPassthrough {
            label: "eventfd:init=7,flags=0".to_string(),
        };
        let epoll_backing = ShadowBacking::HostPassthrough {
            label: "epoll:browser".to_string(),
        };
        for (fd, backing) in [
            (6, queue_a_backing.clone()),
            (7, queue_b_backing.clone()),
            (8, eventfd_backing.clone()),
            (9, epoll_backing.clone()),
            (10, scm_a_backing.clone()),
            (11, scm_b_backing.clone()),
        ] {
            fds.insert_shadow_fd_with_backing(
                pid,
                fd,
                None,
                ShadowObject {
                    kind: ShadowKind::HostPassthrough,
                    supervisor_fd: fd,
                },
                backing,
                false,
            )
            .unwrap();
        }

        let epoll_plan = KboxlikeEpollShadowBackingPlan {
            fd_plan: KboxlikeFdShadowBackingPlan {
                host_pid: 2001,
                model_pid: pid,
                model_thread_id: 1,
                fd: 9,
                target: "anon_inode:[eventpoll]".to_string(),
                cloexec: false,
                backing: epoll_backing,
            },
            interests: vec![KboxlikeEpollInterestBackingPlan {
                target_fd: 8,
                events: libc::EPOLLIN as u32,
                data: 0xfeed_cafe,
                target: Some("anon_inode:[eventfd]".to_string()),
                target_kind: Some(crate::kboxlike::snapshot::KboxlikeFdTargetKind::EventFd),
                target_backing: Some(eventfd_backing.clone()),
            }],
        };
        let queued_plan = KboxlikeFdQueuedDataPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 7,
            injector_fd: 6,
            target: "socket:[222]".to_string(),
            receiver_backing: queue_b_backing,
            injector_backing: queue_a_backing,
            bytes: b"sockq".to_vec(),
        };
        let socket_options_plan = KboxlikeFdSocketOptionsPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            fd: 11,
            target: "socket:[444]".to_string(),
            backing: scm_b_backing.clone(),
            int_options: vec![KboxlikeSocketIntOption {
                level: libc::SOL_SOCKET,
                name: libc::SO_PASSCRED,
                value: 1,
            }],
        };
        let scm_plan = KboxlikeFdScmRightsPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 11,
            injector_fd: 10,
            target: "socket:[444]".to_string(),
            receiver_backing: scm_b_backing,
            injector_backing: scm_a_backing.clone(),
            data: b"r".to_vec(),
            passed_fds: vec![8],
            passed_backings: vec![eventfd_backing],
            credentials: Some(KboxlikeUnixCredentials {
                pid: unsafe { libc::getpid() },
                uid: unsafe { libc::getuid() },
                gid: unsafe { libc::getgid() },
            }),
            credential_identity: None,
        };
        let socket_shutdown_plan = KboxlikeFdSocketShutdownPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            fd: 10,
            target: "socket:[333]".to_string(),
            backing: scm_a_backing,
            shutdown: KboxlikeSocketShutdownState {
                read_closed: false,
                write_closed: true,
            },
        };

        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        let summary = rebuilder
            .replay_fd_kernel_state(
                &rebuilt,
                std::slice::from_ref(&epoll_plan),
                std::slice::from_ref(&socket_options_plan),
                std::slice::from_ref(&queued_plan),
                std::slice::from_ref(&socket_shutdown_plan),
                std::slice::from_ref(&scm_plan),
            )
            .unwrap();

        assert_eq!(
            summary,
            KboxlikeFdKernelReplaySummary {
                epoll_interests: 1,
                socket_options: 1,
                queued_bytes: queued_plan.bytes.len(),
                socket_shutdowns: 1,
                scm_rights_messages: 1,
            }
        );

        let queued_receiver_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let mut queued_receiver = File::from(
            rebuilder
                .dup_handle(queued_receiver_shadow.supervisor_fd)
                .unwrap(),
        );
        let mut queued_buf = vec![0u8; queued_plan.bytes.len()];
        queued_receiver.read_exact(&mut queued_buf).unwrap();
        assert_eq!(queued_buf, queued_plan.bytes);

        let scm_receiver_shadow = rebuilt.descriptor(pid, 11).unwrap().shadow.unwrap();
        let scm_receiver = rebuilder
            .dup_handle(scm_receiver_shadow.supervisor_fd)
            .unwrap();
        assert_eq!(
            get_socket_int_option(
                scm_receiver.as_raw_fd(),
                libc::SOL_SOCKET,
                libc::SO_PASSCRED
            )
            .unwrap(),
            1
        );
        let (data, passed, credentials) = recv_one_scm_right(scm_receiver.as_raw_fd(), 1);
        assert_eq!(data, b"r");
        assert_eq!(credentials, scm_plan.credentials);
        let mut value = 0u64;
        let rc = unsafe {
            libc::read(
                passed.as_raw_fd(),
                &mut value as *mut u64 as *mut libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);
        assert_eq!(value, 7);
        let mut eof_buf = [0u8; 1];
        let eof_read = unsafe {
            libc::read(
                scm_receiver.as_raw_fd(),
                eof_buf.as_mut_ptr() as *mut libc::c_void,
                eof_buf.len(),
            )
        };
        assert_eq!(eof_read, 0);
        let value = 1u64;
        let rc = unsafe {
            libc::write(
                passed.as_raw_fd(),
                &value as *const u64 as *const libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);

        let epoll_shadow = rebuilt.descriptor(pid, 9).unwrap().shadow.unwrap();
        let epoll_handle = rebuilder.dup_handle(epoll_shadow.supervisor_fd).unwrap();
        let mut events = [libc::epoll_event { events: 0, u64: 0 }; 1];
        let ready =
            unsafe { libc::epoll_wait(epoll_handle.as_raw_fd(), events.as_mut_ptr(), 1, 0) };
        assert_eq!(ready, 1);
        let event_data = unsafe { std::ptr::addr_of!(events[0].u64).read_unaligned() };
        assert_eq!(event_data, 0xfeed_cafe);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_queued_data_restores_pipe_buffer() {
        let rootfs = test_rootfs("queued-pipe");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let read_backing = ShadowBacking::HostPassthrough {
            label: "pipe:network:0".to_string(),
        };
        let write_backing = ShadowBacking::HostPassthrough {
            label: "pipe:network:1".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            3,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 3,
            },
            read_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            4,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 4,
            },
            write_backing.clone(),
            false,
        )
        .unwrap();

        let plan = KboxlikeFdQueuedDataPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 3,
            injector_fd: 4,
            target: "pipe:[12345]".to_string(),
            receiver_backing: read_backing,
            injector_backing: write_backing,
            bytes: b"pipeq".to_vec(),
        };
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_queued_data(&rebuilt, std::slice::from_ref(&plan))
                .unwrap(),
            plan.bytes.len()
        );

        let read_shadow = rebuilt.descriptor(pid, 3).unwrap().shadow.unwrap();
        let mut reader = File::from(rebuilder.dup_handle(read_shadow.supervisor_fd).unwrap());
        let mut buf = vec![0u8; plan.bytes.len()];
        reader.read_exact(&mut buf).unwrap();
        assert_eq!(buf, plan.bytes);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_queued_data_restores_socketpair_buffer() {
        let rootfs = test_rootfs("queued-socketpair");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:0".to_string(),
        };
        let b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:1".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            6,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 6,
            },
            a_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            7,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 7,
            },
            b_backing.clone(),
            false,
        )
        .unwrap();

        let plan = KboxlikeFdQueuedDataPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 7,
            injector_fd: 6,
            target: "socket:[222]".to_string(),
            receiver_backing: b_backing,
            injector_backing: a_backing,
            bytes: b"sockq".to_vec(),
        };
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_queued_data(&rebuilt, std::slice::from_ref(&plan))
                .unwrap(),
            plan.bytes.len()
        );

        let receiver_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let mut receiver = File::from(rebuilder.dup_handle(receiver_shadow.supervisor_fd).unwrap());
        let mut buf = vec![0u8; plan.bytes.len()];
        receiver.read_exact(&mut buf).unwrap();
        assert_eq!(buf, plan.bytes);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_socket_options_restores_socketpair_options() {
        let rootfs = test_rootfs("socket-options");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:0".to_string(),
        };
        let b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:1".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            6,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 6,
            },
            a_backing,
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            7,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 7,
            },
            b_backing.clone(),
            false,
        )
        .unwrap();

        let plan = KboxlikeFdSocketOptionsPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            fd: 7,
            target: "socket:[222]".to_string(),
            backing: b_backing,
            int_options: vec![KboxlikeSocketIntOption {
                level: libc::SOL_SOCKET,
                name: libc::SO_PASSCRED,
                value: 1,
            }],
        };
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_socket_options(&rebuilt, std::slice::from_ref(&plan))
                .unwrap(),
            1
        );

        let receiver_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let receiver = rebuilder.dup_handle(receiver_shadow.supervisor_fd).unwrap();
        assert_eq!(
            get_socket_int_option(receiver.as_raw_fd(), libc::SOL_SOCKET, libc::SO_PASSCRED)
                .unwrap(),
            1
        );

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_socket_shutdown_restores_socketpair_write_eof() {
        let rootfs = test_rootfs("socket-shutdown");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:0".to_string(),
        };
        let b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:crashpad:1".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            6,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 6,
            },
            a_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            7,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 7,
            },
            b_backing,
            false,
        )
        .unwrap();

        let plan = KboxlikeFdSocketShutdownPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            fd: 6,
            target: "socket:[111]".to_string(),
            backing: a_backing,
            shutdown: KboxlikeSocketShutdownState {
                read_closed: false,
                write_closed: true,
            },
        };
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_socket_shutdown(&rebuilt, std::slice::from_ref(&plan))
                .unwrap(),
            1
        );

        let peer_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let peer = rebuilder.dup_handle(peer_shadow.supervisor_fd).unwrap();
        let mut buf = [0u8; 1];
        let read = unsafe {
            libc::read(
                peer.as_raw_fd(),
                buf.as_mut_ptr() as *mut libc::c_void,
                buf.len(),
            )
        };
        assert_eq!(read, 0);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_scm_rights_restores_passed_eventfd() {
        let rootfs = test_rootfs("scm-rights");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker:0".to_string(),
        };
        let b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker:1".to_string(),
        };
        let eventfd_backing = ShadowBacking::HostPassthrough {
            label: "eventfd:init=7,flags=0".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            6,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 6,
            },
            a_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            7,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 7,
            },
            b_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            8,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 8,
            },
            eventfd_backing.clone(),
            false,
        )
        .unwrap();

        let plan = KboxlikeFdScmRightsPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 7,
            injector_fd: 6,
            target: "socket:[222]".to_string(),
            receiver_backing: b_backing,
            injector_backing: a_backing,
            data: b"r".to_vec(),
            passed_fds: vec![8],
            passed_backings: vec![eventfd_backing],
            credentials: Some(KboxlikeUnixCredentials {
                pid: unsafe { libc::getpid() },
                uid: unsafe { libc::getuid() },
                gid: unsafe { libc::getgid() },
            }),
            credential_identity: None,
        };
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        let receiver_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let receiver = rebuilder.dup_handle(receiver_shadow.supervisor_fd).unwrap();
        set_socket_int_option(receiver.as_raw_fd(), libc::SOL_SOCKET, libc::SO_PASSCRED, 1)
            .unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_scm_rights(&rebuilt, std::slice::from_ref(&plan))
                .unwrap(),
            1
        );

        let (data, passed, credentials) = recv_one_scm_right(receiver.as_raw_fd(), 1);
        assert_eq!(data, b"r");
        assert_eq!(credentials, plan.credentials);
        let mut value = 0u64;
        let rc = unsafe {
            libc::read(
                passed.as_raw_fd(),
                &mut value as *mut u64 as *mut libc::c_void,
                std::mem::size_of::<u64>(),
            )
        };
        assert_eq!(rc, std::mem::size_of::<u64>() as isize);
        assert_eq!(value, 7);

        fs::remove_dir_all(rootfs).unwrap();
    }

    #[cfg(target_os = "linux")]
    #[test]
    fn replay_fd_scm_rights_remaps_credentials_to_replacement_pid() {
        let rootfs = test_rootfs("scm-rights-remap");
        let mut fds = KboxlikeFdSystem::new();
        let pid = fds.spawn_init_with_exe("/chrome");
        let a_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker-remap:0".to_string(),
        };
        let b_backing = ShadowBacking::HostPassthrough {
            label: "socketpair:broker-remap:1".to_string(),
        };
        let eventfd_backing = ShadowBacking::HostPassthrough {
            label: "eventfd:init=9,flags=0".to_string(),
        };
        fds.insert_shadow_fd_with_backing(
            pid,
            6,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 6,
            },
            a_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            7,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 7,
            },
            b_backing.clone(),
            false,
        )
        .unwrap();
        fds.insert_shadow_fd_with_backing(
            pid,
            8,
            None,
            ShadowObject {
                kind: ShadowKind::HostPassthrough,
                supervisor_fd: 8,
            },
            eventfd_backing.clone(),
            false,
        )
        .unwrap();

        let old_sender_pid = 424_242;
        let model_thread_id = 99;
        let replacement_pid = unsafe { libc::getpid() };
        let plan = KboxlikeFdScmRightsPlan {
            host_pid: 2001,
            model_pid: pid,
            model_thread_id: 1,
            receiver_fd: 7,
            injector_fd: 6,
            target: "socket:[222]".to_string(),
            receiver_backing: b_backing,
            injector_backing: a_backing,
            data: b"r".to_vec(),
            passed_fds: vec![8],
            passed_backings: vec![eventfd_backing],
            credentials: Some(KboxlikeUnixCredentials {
                pid: old_sender_pid,
                uid: unsafe { libc::getuid() },
                gid: unsafe { libc::getgid() },
            }),
            credential_identity: Some(KboxlikeTraceeIdentity {
                host_pid: old_sender_pid,
                model_pid: pid,
                model_thread_id,
            }),
        };
        let mut replacement_host_pids = BTreeMap::new();
        replacement_host_pids.insert(model_thread_id, replacement_pid);
        let mut rebuilder = HostShadowRebuilder::new(&rootfs);
        let rebuilt =
            KboxlikeFdSystem::restore_rebuilding_shadows(fds.snapshot(), &mut rebuilder).unwrap();
        let receiver_shadow = rebuilt.descriptor(pid, 7).unwrap().shadow.unwrap();
        let receiver = rebuilder.dup_handle(receiver_shadow.supervisor_fd).unwrap();
        set_socket_int_option(receiver.as_raw_fd(), libc::SOL_SOCKET, libc::SO_PASSCRED, 1)
            .unwrap();
        assert_eq!(
            rebuilder
                .replay_fd_scm_rights_with_replacement_pids(
                    &rebuilt,
                    std::slice::from_ref(&plan),
                    &replacement_host_pids,
                )
                .unwrap(),
            1
        );

        let (data, _passed, credentials) = recv_one_scm_right(receiver.as_raw_fd(), 1);
        assert_eq!(data, b"r");
        assert_eq!(
            credentials,
            Some(KboxlikeUnixCredentials {
                pid: replacement_pid,
                uid: unsafe { libc::getuid() },
                gid: unsafe { libc::getgid() },
            })
        );

        fs::remove_dir_all(rootfs).unwrap();
    }
}
