use rppal_pfd::{
	ChipSelect, HardwareAddress, OutputPin, PiFaceDigital, PiFaceDigitalError, SpiBus, SpiMode,
};

use crate::drivers::RelayDriver;
use crate::errors::EmgauwaError;

pub struct PifaceDriver {
	pub pfd_pin: OutputPin,
}

impl PifaceDriver {
	pub fn new(pin: u8, pfd: &Option<PiFaceDigital>) -> Result<Self, EmgauwaError> {
		let pfd = pfd.as_ref().ok_or(EmgauwaError::Hardware(String::from(
			"PiFaceDigital not initialized",
		)))?;
		let pfd_pin = pfd.get_output_pin(pin)?;
		Ok(Self { pfd_pin })
	}

	pub fn init_piface() -> Result<PiFaceDigital, EmgauwaError> {
		let mut pfd = PiFaceDigital::new(
			HardwareAddress::new(0)?,
			SpiBus::Spi0,
			ChipSelect::Cs0,
			100_000,
			SpiMode::Mode0,
		)?;
		pfd.init()?;

		Ok(pfd)
	}
}

impl RelayDriver for PifaceDriver {
	fn set(&mut self, value: bool) -> Result<(), EmgauwaError> {
		if self.get_high(value) {
			self.pfd_pin.set_high().map_err(PiFaceDigitalError::from)?;
		} else {
			self.pfd_pin.set_low().map_err(PiFaceDigitalError::from)?;
		}
		Ok(())
	}

	fn get_pin(&self) -> u8 {
		self.pfd_pin.get_pin_number()
	}

	fn get_inverted(&self) -> bool {
		false
	}
}