use crate as cindy;

use uuid::Uuid;

#[doc(hidden)]
#[crate::wire]
pub struct RemoteFnPayload {
    pub uuid: Uuid,
    pub fn_id: String,
    pub data: Vec<u8>,
}

#[doc(hidden)]
#[crate::wire]
pub enum RemoteFnResponse {
    Ok(Vec<u8>),
    Panic(String),
}

#[doc(hidden)]
#[crate::wire]
pub struct RemoteFnResponsePayload {
    pub uuid: Uuid,
    pub response: RemoteFnResponse,
}

#[doc(hidden)]
pub fn quarantine_stdio() -> (tokio::fs::File, tokio::fs::File) {
    let saved_in = nix::unistd::dup(std::io::stdin()).expect("Couldn't dup RPC stdin off FD 0");
    let saved_out = nix::unistd::dup(std::io::stdout()).expect("Couldn't dup RPC stdout off FD 1");

    nix::unistd::dup2_stdout(std::io::stderr()).expect("Couldn't redirect FD 1 to stderr");

    let dev_null =
        std::fs::File::open("/dev/null").expect("Couldn't open /dev/null for FD 0 redirect");
    nix::unistd::dup2_stdin(&dev_null).expect("Couldn't redirect FD 0 to /dev/null");
    // `dev_null` drops here; the kernel still holds the underlying file
    // via FD 0, which `dup2_stdin` just pointed at it.

    (
        tokio::fs::File::from_std(std::fs::File::from(saved_in)),
        tokio::fs::File::from_std(std::fs::File::from(saved_out)),
    )
}
