use emgauwa_lib::errors::EmgauwaError;
use emgauwa_lib::settings;
use serde_derive::Deserialize;

use crate::driver::Driver;

#[derive(Clone, Debug, Deserialize)]
#[serde(default)]
#[allow(unused)]
pub struct Relay {
	pub driver: Driver,
	pub name: String,
	pub number: Option<i64>,
	pub pin: u8,
	pub inverted: bool,
	pub pulse: Option<u64>,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(default)]
#[allow(unused)]
pub struct Settings {
	pub server: settings::Server,
	pub database: String,
	pub permissions: settings::Permissions,
	pub logging: settings::Logging,

	pub name: String,
	pub relays: Vec<Relay>,
}

impl Default for Settings {
	fn default() -> Self {
		Settings {
			server: settings::Server::default(),
			database: String::from("sqlite://emgauwa-controller.sqlite"),
			permissions: settings::Permissions::default(),
			logging: settings::Logging::default(),

			name: String::from("Emgauwa Controller"),
			relays: Vec::new(),
		}
	}
}

impl Default for Relay {
	fn default() -> Self {
		Relay {
			driver: Driver::Gpio,
			number: None,
			name: String::from("Relay"),
			pin: 0,
			inverted: false,
			pulse: None,
		}
	}
}

pub fn init() -> Result<Settings, EmgauwaError> {
	let mut settings: Settings = settings::load("controller", "CONTROLLER")?;

	for (num, relay) in settings.relays.iter_mut().enumerate() {
		if relay.number.is_none() {
			relay.number = Some(num as i64);
		}
	}

	Ok(settings)
}

impl Settings {
	pub fn get_relay(&self, number: i64) -> Option<&Relay> {
		self.relays.iter().find(|r| r.number == Some(number))
	}
}