use {
    crate::devices::Device::{Character, Vterm},
    core::fmt::{Arguments, Error, Write},
    kernel::device_interface::character::CharacterDevice,
};

#[derive(Debug, Clone)]
pub struct StdIO {
    device: String,
}

impl StdIO {
    pub fn new(device: String) -> StdIO {
        StdIO { device }
    }
    pub fn write(&mut self, args: Arguments) -> Result<(), Error> {
        use crate::devices::DEVICE_TABLE;
        let mut dt = DEVICE_TABLE.lock();
        let key_device = dt.devices.get_mut(&self.device).unwrap();

        match key_device {
            Character(dev) => {
                let mut buf = String::new();
                write!(buf, "{}", args).unwrap();
                for c in buf.chars() {
                    dev.write_char(c);
                }
                Ok(())
            }
            Vterm(vterm) => {
                let mut buf = String::new();
                write!(buf, "{}", args).unwrap();
                for c in buf.chars() {
                    vterm.write_char(c);
                }
                Ok(())
            }
        }
    }

    pub fn read(&mut self) {
        use crate::devices::DEVICE_TABLE;
        let mut dt = DEVICE_TABLE.lock();
        let key_device = dt.devices.get_mut(&self.device).unwrap();

        match key_device {
            Character(dev) => {
                let mut buf = String::new();
                dev.read_char().map(|c| buf.push(c));
                println!("{}", buf);
            }
            Vterm(vterm) => {
                let mut buf = String::new();
                vterm.read_char().map(|c| buf.push(c));
                println!("{}", buf);
            }
        }
    }
}
