pub mod character_devs;
pub mod id;
pub mod pci_inner;

use hashbrown::HashMap;
mod dev_vterm;
use crate::devices::dev_vterm::VTerm;
use kernel::device_interface::character::CharacterDevice;
// FIXME: This is a hack to hold a device.
// #[derive(Debug)]
pub enum Device {
    Character(Box<dyn CharacterDevice>),
    Vterm(VTerm),
}
unsafe impl Sync for Device {}
unsafe impl Send for Device {}

pub struct DeviceTable {
    pub devices: HashMap<String, Device>,
}
use self::character_devs::{dev_null::DevNull, dev_unicode::DevUnicode, dev_zero::DevZero};
pub use self::Device::*;
impl DeviceTable {
    pub fn new() -> Self {
        let mut table: HashMap<String, Device> = HashMap::new();
        table.insert("null".to_string(), Character(Box::new(DevNull)));
        table.insert("zero".to_string(), Character(Box::new(DevZero)));
        table.insert(
            "unicode".to_string(),
            Character(Box::new(DevUnicode {
                next_write_char: 0x00 as char,
                next_read_char: 0x00 as char,
            })),
        );
        table.insert("kvterm".to_string(), Vterm(VTerm::new()));
        DeviceTable { devices: table }
    }
}

lazy_static::lazy_static!(
    pub static ref DEVICE_TABLE: spin::Mutex<DeviceTable> =
    spin::Mutex::new(DeviceTable::new());
);
