use std::{
    io::{self, Stdout},
    os::{
        fd::AsRawFd,
        yggdrasil::io::terminal::{
            get_terminal_size, set_terminal_options, update_terminal_options, TerminalOptions,
        },
    },
};

pub struct RawMode(TerminalOptions);

impl RawMode {
    /// # Safety
    ///
    /// May leave the terminal in broken state, unsafe.
    pub unsafe fn enter<F: AsRawFd>(stdin: &F) -> io::Result<Self> {
        update_terminal_options(stdin, |_| TerminalOptions::raw_input()).map(Self)
    }

    /// # Safety
    ///
    /// May leave the terminal in broken state, unsafe.
    pub unsafe fn leave<F: AsRawFd>(&self, stdin: &F) {
        set_terminal_options(stdin, &self.0).ok();
    }
}

pub unsafe fn terminal_size(stdout: &Stdout) -> io::Result<(usize, usize)> {
    match get_terminal_size(stdout) {
        Ok(size) => Ok((size.columns, size.rows)),
        Err(_) => Ok((80, 20)),
    }
}
