pub use abi::io::{
    TerminalInputOptions, TerminalLineOptions, TerminalOptions, TerminalOutputOptions, TerminalSize,
};

use abi::{error::Error, io::RawFd, process::ProcessGroupId};

use super::device::{self, device_request};

pub fn get_terminal_options(fd: RawFd) -> Result<TerminalOptions, Error> {
    let mut buffer = [0; 64];
    device_request::<device::GetTerminalOptions>(fd, &mut buffer, &())
}
pub fn set_terminal_options(fd: RawFd, options: &TerminalOptions) -> Result<(), Error> {
    let mut buffer = [0; 64];
    device_request::<device::SetTerminalOptions>(fd, &mut buffer, options)
}
pub fn update_terminal_options<F: FnOnce(TerminalOptions) -> TerminalOptions>(
    fd: RawFd,
    mapper: F,
) -> Result<TerminalOptions, Error> {
    let old = get_terminal_options(fd)?;
    let new = mapper(old);
    set_terminal_options(fd, &new)?;
    Ok(old)
}

pub fn get_terminal_size(fd: RawFd) -> Result<TerminalSize, Error> {
    let mut buffer = [0; 32];
    device_request::<device::GetTerminalSize>(fd, &mut buffer, &())
}
pub fn set_terminal_size(fd: RawFd, size: &TerminalSize) -> Result<(), Error> {
    let mut buffer = [0; 32];
    device_request::<device::SetTerminalSize>(fd, &mut buffer, size)
}

pub fn set_terminal_group(fd: RawFd, group: ProcessGroupId) -> Result<(), Error> {
    let mut buffer = [0; 8];
    device_request::<device::SetTerminalGroup>(fd, &mut buffer, &group)
}

pub fn is_terminal(fd: RawFd) -> bool {
    let mut buffer = [0; 0];
    device_request::<device::IsTerminal>(fd, &mut buffer, &()).is_ok()
}
