//! Create master and slave virtual pseudo-terminals (PTYs)

pub use libc::pid_t as SessionId;
pub use libc::winsize as Winsize;

use std::ffi::CStr;
use std::io;
#[cfg(not(target_os = "aix"))]
use std::mem;
use std::os::unix::prelude::*;

use crate::errno::Errno;
#[cfg(not(target_os = "aix"))]
use crate::sys::termios::Termios;
#[cfg(feature = "process")]
use crate::unistd::ForkResult;
#[cfg(all(feature = "process", not(target_os = "aix")))]
use crate::unistd::Pid;
use crate::{fcntl, unistd, Result};

/// Representation of a master/slave pty pair
///
/// This is returned by [`openpty`].
#[derive(Debug)]
pub struct OpenptyResult {
    /// The master port in a virtual pty pair
    pub master: OwnedFd,
    /// The slave port in a virtual pty pair
    pub slave: OwnedFd,
}

feature! {
#![feature = "process"]
/// Representation of a master with a forked pty
///
/// This is returned by [`forkpty`].
#[derive(Debug)]
pub struct ForkptyResult {
    /// The master port in a virtual pty pair
    pub master: OwnedFd,
    /// Metadata about forked process
    pub fork_result: ForkResult,
}
}

/// Representation of the Master device in a master/slave pty pair
///
/// While this datatype is a thin wrapper around `OwnedFd`, it enforces that the available PTY
/// functions are given the correct file descriptor.
#[derive(Debug)]
pub struct PtyMaster(OwnedFd);

impl AsRawFd for PtyMaster {
    fn as_raw_fd(&self) -> RawFd {
        self.0.as_raw_fd()
    }
}

impl IntoRawFd for PtyMaster {
    fn into_raw_fd(self) -> RawFd {
        let fd = self.0;
        fd.into_raw_fd()
    }
}

impl io::Read for PtyMaster {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        unistd::read(self.0.as_raw_fd(), buf).map_err(io::Error::from)
    }
}

impl io::Write for PtyMaster {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        unistd::write(&self.0, buf).map_err(io::Error::from)
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl io::Read for &PtyMaster {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        unistd::read(self.0.as_raw_fd(), buf).map_err(io::Error::from)
    }
}

impl io::Write for &PtyMaster {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        unistd::write(&self.0, buf).map_err(io::Error::from)
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

/// Grant access to a slave pseudoterminal (see
/// [`grantpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
///
/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the
/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave.
#[inline]
pub fn grantpt(fd: &PtyMaster) -> Result<()> {
    if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 {
        return Err(Errno::last());
    }

    Ok(())
}

/// Open a pseudoterminal device (see
/// [`posix_openpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
///
/// `posix_openpt()` returns a file descriptor to an existing unused pseudoterminal master device.
///
/// # Examples
///
/// A common use case with this function is to open both a master and slave PTY pair. This can be
/// done as follows:
///
/// ```
/// use std::path::Path;
/// use nix::fcntl::{OFlag, open};
/// use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
/// use nix::sys::stat::Mode;
///
/// # #[allow(dead_code)]
/// # fn run() -> nix::Result<()> {
/// // Open a new PTY master
/// let master_fd = posix_openpt(OFlag::O_RDWR)?;
///
/// // Allow a slave to be generated for it
/// grantpt(&master_fd)?;
/// unlockpt(&master_fd)?;
///
/// // Get the name of the slave
/// let slave_name = unsafe { ptsname(&master_fd) }?;
///
/// // Try to open the slave
/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
    let fd = unsafe { libc::posix_openpt(flags.bits()) };

    if fd < 0 {
        return Err(Errno::last());
    }

    Ok(PtyMaster(unsafe { OwnedFd::from_raw_fd(fd) }))
}

/// Get the name of the slave pseudoterminal (see
/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html))
///
/// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master
/// referred to by `fd`.
///
/// This value is useful for opening the slave pty once the master has already been opened with
/// `posix_openpt()`.
///
/// # Safety
///
/// `ptsname()` mutates global variables and is *not* threadsafe.
/// Mutating global variables is always considered `unsafe` by Rust and this
/// function is marked as `unsafe` to reflect that.
///
/// For a threadsafe and non-`unsafe` alternative on Linux, see `ptsname_r()`.
#[inline]
pub unsafe fn ptsname(fd: &PtyMaster) -> Result<String> {
    let name_ptr = unsafe { libc::ptsname(fd.as_raw_fd()) };
    if name_ptr.is_null() {
        return Err(Errno::last());
    }

    let name = unsafe { CStr::from_ptr(name_ptr) };
    Ok(name.to_string_lossy().into_owned())
}

/// Get the name of the slave pseudoterminal (see
/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html))
///
/// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master
/// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the
/// POSIX standard and is instead a Linux-specific extension.
///
/// This value is useful for opening the slave ptty once the master has already been opened with
/// `posix_openpt()`.
#[cfg(linux_android)]
#[inline]
pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
    let mut name_buf = Vec::<libc::c_char>::with_capacity(64);
    let name_buf_ptr = name_buf.as_mut_ptr();
    let cname = unsafe {
        let cap = name_buf.capacity();
        if libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, cap) != 0 {
            return Err(crate::Error::last());
        }
        CStr::from_ptr(name_buf.as_ptr())
    };

    let name = cname.to_string_lossy().into_owned();
    Ok(name)
}

/// Unlock a pseudoterminal master/slave pseudoterminal pair (see
/// [`unlockpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html))
///
/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
/// referred to by `fd`. This must be called before trying to open the slave side of a
/// pseudoterminal.
#[inline]
pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
    if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 {
        return Err(Errno::last());
    }

    Ok(())
}

/// Create a new pseudoterminal, returning the slave and master file descriptors
/// in `OpenptyResult`
/// (see [`openpty`](https://man7.org/linux/man-pages/man3/openpty.3.html)).
///
/// If `winsize` is not `None`, the window size of the slave will be set to
/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
/// terminal settings of the slave will be set to the values in `termios`.
#[inline]
#[cfg(not(target_os = "aix"))]
pub fn openpty<
    'a,
    'b,
    T: Into<Option<&'a Winsize>>,
    U: Into<Option<&'b Termios>>,
>(
    winsize: T,
    termios: U,
) -> Result<OpenptyResult> {
    use std::ptr;

    let mut slave = mem::MaybeUninit::<libc::c_int>::uninit();
    let mut master = mem::MaybeUninit::<libc::c_int>::uninit();
    let ret = {
        match (termios.into(), winsize.into()) {
            (Some(termios), Some(winsize)) => {
                let inner_termios = termios.get_libc_termios();
                unsafe {
                    libc::openpty(
                        master.as_mut_ptr(),
                        slave.as_mut_ptr(),
                        ptr::null_mut(),
                        &*inner_termios as *const libc::termios as *mut _,
                        winsize as *const Winsize as *mut _,
                    )
                }
            }
            (None, Some(winsize)) => unsafe {
                libc::openpty(
                    master.as_mut_ptr(),
                    slave.as_mut_ptr(),
                    ptr::null_mut(),
                    ptr::null_mut(),
                    winsize as *const Winsize as *mut _,
                )
            },
            (Some(termios), None) => {
                let inner_termios = termios.get_libc_termios();
                unsafe {
                    libc::openpty(
                        master.as_mut_ptr(),
                        slave.as_mut_ptr(),
                        ptr::null_mut(),
                        &*inner_termios as *const libc::termios as *mut _,
                        ptr::null_mut(),
                    )
                }
            }
            (None, None) => unsafe {
                libc::openpty(
                    master.as_mut_ptr(),
                    slave.as_mut_ptr(),
                    ptr::null_mut(),
                    ptr::null_mut(),
                    ptr::null_mut(),
                )
            },
        }
    };

    Errno::result(ret)?;

    unsafe {
        Ok(OpenptyResult {
            master: OwnedFd::from_raw_fd(master.assume_init()),
            slave: OwnedFd::from_raw_fd(slave.assume_init()),
        })
    }
}

feature! {
#![feature = "process"]
/// Create a new pseudoterminal, returning the master file descriptor and forked pid.
/// in `ForkptyResult`
/// (see [`forkpty`](https://man7.org/linux/man-pages/man3/forkpty.3.html)).
///
/// If `winsize` is not `None`, the window size of the slave will be set to
/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
/// terminal settings of the slave will be set to the values in `termios`.
///
/// # Safety
///
/// In a multithreaded program, only [async-signal-safe] functions like `pause`
/// and `_exit` may be called by the child (the parent isn't restricted). Note
/// that memory allocation may **not** be async-signal-safe and thus must be
/// prevented.
///
/// Those functions are only a small subset of your operating system's API, so
/// special care must be taken to only invoke code you can control and audit.
///
/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html
#[cfg(not(target_os = "aix"))]
pub unsafe fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(
    winsize: T,
    termios: U,
) -> Result<ForkptyResult> {
    use std::ptr;

    let mut master = mem::MaybeUninit::<libc::c_int>::uninit();

    let term = match termios.into() {
        Some(termios) => {
            let inner_termios = termios.get_libc_termios();
            &*inner_termios as *const libc::termios as *mut _
        },
        None => ptr::null_mut(),
    };

    let win = winsize
        .into()
        .map(|ws| ws as *const Winsize as *mut _)
        .unwrap_or(ptr::null_mut());

    let res = unsafe { libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win) };

    let fork_result = Errno::result(res).map(|res| match res {
        0 => ForkResult::Child,
        res => ForkResult::Parent { child: Pid::from_raw(res) },
    })?;

    Ok(ForkptyResult {
        master: unsafe { OwnedFd::from_raw_fd( master.assume_init() ) },
        fork_result,
    })
}
}
