use base::error;
use base::SendTube;
use base::VmEventType;
use snapshot::AnySnapshot;
use crate::pci::CrosvmDeviceId;
use crate::BusAccessInfo;
use crate::BusDevice;
use crate::DeviceId;
use crate::Suspendable;
pub struct I8042Device {
    reset_evt_wrtube: SendTube,
}
impl I8042Device {
    pub fn new(reset_evt_wrtube: SendTube) -> I8042Device {
        I8042Device { reset_evt_wrtube }
    }
}
impl BusDevice for I8042Device {
    fn device_id(&self) -> DeviceId {
        CrosvmDeviceId::I8042.into()
    }
    fn debug_label(&self) -> String {
        "i8042".to_owned()
    }
    fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
        if data.len() == 1 && info.address == 0x64 {
            data[0] = 0x0;
        } else if data.len() == 1 && info.address == 0x61 {
            data[0] = 0x20;
        }
    }
    fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
        if data.len() == 1 && data[0] == 0xfe && info.address == 0x64 {
            if let Err(e) = self
                .reset_evt_wrtube
                .send::<VmEventType>(&VmEventType::Reset)
            {
                error!("failed to trigger i8042 reset event: {}", e);
            }
        }
    }
}
impl Suspendable for I8042Device {
    fn snapshot(&mut self) -> anyhow::Result<AnySnapshot> {
        AnySnapshot::to_any(())
    }
    fn restore(&mut self, _data: AnySnapshot) -> anyhow::Result<()> {
        Ok(())
    }
    fn sleep(&mut self) -> anyhow::Result<()> {
        Ok(())
    }
    fn wake(&mut self) -> anyhow::Result<()> {
        Ok(())
    }
}