use embedded_hal::i2c::{ErrorKind, ErrorType, I2c, Operation, SevenBitAddress};
use log::trace;
use std::fmt::{Display, Formatter};

#[derive(Debug)]
pub struct SimMcp23017 {}

impl SimMcp23017 {
    pub fn new() -> Self {
        trace!("SimMcp23017::new()");
        Self {}
    }
}

#[derive(Debug)]
pub struct ErrorWrapper(anyhow::Error);

impl embedded_hal::i2c::Error for ErrorWrapper {
    fn kind(&self) -> ErrorKind {
        ErrorKind::Other
    }
}

impl Display for ErrorWrapper {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::error::Error for ErrorWrapper {}

impl ErrorType for SimMcp23017 {
    type Error = ErrorWrapper;
}

impl I2c for SimMcp23017 {
    fn transaction(
        &mut self,
        address: SevenBitAddress,
        operations: &mut [Operation<'_>],
    ) -> Result<(), Self::Error> {
        trace!(
            "SimMcp23017::transaction(self: {self:?}, address: {address}, operations: {operations:?})"
        );
        for operation in operations {
            match operation {
                Operation::Write(_write_buffer) => {
                    // Ignore incoming write operations
                }
                Operation::Read(_read_buffer) => {
                    todo!("SimMcp23017 read")
                }
            }
        }
        Ok(())
    }
}
