use std::{
    io::{self, Read, Write},
    path::Path,
};

use crate::sys::{I2CMaster as SysI2CMaster, i2c::I2CMasterImpl};

pub use crate::sys::I2CMasterConfig;

pub struct I2CMaster(I2CMasterImpl);

impl Read for I2CMaster {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl Write for I2CMaster {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl I2CMaster {
    pub fn open<P: AsRef<Path>>(device: P, config: &I2CMasterConfig) -> io::Result<Self> {
        I2CMasterImpl::open(device, config).map(Self)
    }

    pub fn set_slave_address(&mut self, address: u16) -> io::Result<()> {
        self.0.set_slave_address(address)
    }

    pub fn set_speed_hz(&mut self, speed_hz: u32) -> io::Result<()> {
        self.0.set_speed_hz(speed_hz)
    }

    pub fn smbus_read(&mut self, reg: u8, data: &mut [u8]) -> io::Result<usize> {
        self.0.smbus_read(reg, data)
    }

    pub fn smbus_write(&mut self, reg: u8, data: &[u8]) -> io::Result<usize> {
        self.0.smbus_write(reg, data)
    }
}
