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

#[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(())
            }
            Block(_) => todo!(),
        }
    }

    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);
            }
            Block(_) => todo!(),
        }
    }
}