From 45409168d6ad2e697a234ba1266b085d877eeeb3 Mon Sep 17 00:00:00 2001
From: Tobias Reisinger <tobias@msrg.cc>
Date: Tue, 28 May 2024 21:17:29 +0200
Subject: [PATCH] Improve handling of override_schedule

---
 src/handlers/v1/relays.rs | 54 +++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/src/handlers/v1/relays.rs b/src/handlers/v1/relays.rs
index 199fa20..a03ac1b 100644
--- a/src/handlers/v1/relays.rs
+++ b/src/handlers/v1/relays.rs
@@ -3,22 +3,40 @@ use actix_web::{get, post, put, web, HttpResponse};
 use emgauwa_common::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbTag};
 use emgauwa_common::errors::{DatabaseError, EmgauwaError};
 use emgauwa_common::models::{convert_db_list, FromDbModel, Relay};
-use emgauwa_common::types::{
-	ControllerWsAction, EmgauwaUid, RequestRelayPulse, RequestRelayUpdate,
-};
+use emgauwa_common::types::{ControllerWsAction, EmgauwaUid, RequestRelayPulse, RequestRelayUpdate};
 use sqlx::{Pool, Sqlite};
 
 use crate::app_state;
 use crate::app_state::AppState;
 use crate::handlers::EmgauwaMessage;
 
+pub async fn get_stated_relays(app_state: &Addr<AppState>) -> Result<Vec<Relay>, EmgauwaError> {
+	app_state.send(app_state::GetRelays {}).await?
+}
+
+pub async fn load_state_for_relay(relay: &mut Relay, app_state: &Addr<AppState>) -> Result<(), EmgauwaError>{
+	let stated_relays = get_stated_relays(app_state).await?;
+	relay.find_and_apply_state(&stated_relays);
+	Ok(())
+}
+
+pub async fn load_state_for_relays(relays: &mut Vec<Relay>, app_state: &Addr<AppState>) -> Result<(), EmgauwaError>{
+	let stated_relays = get_stated_relays(app_state).await?;
+	relays.iter_mut().for_each(|r| r.find_and_apply_state(&stated_relays));
+	Ok(())
+}
+
 #[get("/relays")]
-pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, EmgauwaError> {
+pub async fn index(
+	pool: web::Data<Pool<Sqlite>>,
+	app_state: web::Data<Addr<AppState>>,
+) -> Result<HttpResponse, EmgauwaError> {
 	let mut pool_conn = pool.acquire().await?;
 
 	let db_relays = DbRelay::get_all(&mut pool_conn).await?;
 
-	let relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+	let mut relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+	load_state_for_relays(&mut relays, &app_state).await?;
 
 	Ok(HttpResponse::Ok().json(relays))
 }
@@ -26,6 +44,7 @@ pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, Emgauw
 #[get("/relays/tag/{tag}")]
 pub async fn tagged(
 	pool: web::Data<Pool<Sqlite>>,
+	app_state: web::Data<Addr<AppState>>,
 	path: web::Path<(String,)>,
 ) -> Result<HttpResponse, EmgauwaError> {
 	let mut pool_conn = pool.acquire().await?;
@@ -36,7 +55,9 @@ pub async fn tagged(
 		.ok_or(DatabaseError::NotFound)?;
 
 	let db_relays = DbRelay::get_by_tag(&mut pool_conn, &tag_db).await?;
-	let relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+
+	let mut relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+	load_state_for_relays(&mut relays, &app_state).await?;
 
 	Ok(HttpResponse::Ok().json(relays))
 }
@@ -44,6 +65,7 @@ pub async fn tagged(
 #[get("/controllers/{controller_id}/relays")]
 pub async fn index_for_controller(
 	pool: web::Data<Pool<Sqlite>>,
+	app_state: web::Data<Addr<AppState>>,
 	path: web::Path<(String,)>,
 ) -> Result<HttpResponse, EmgauwaError> {
 	let mut pool_conn = pool.acquire().await?;
@@ -57,13 +79,16 @@ pub async fn index_for_controller(
 
 	let db_relays = controller.get_relays(&mut pool_conn).await?;
 
-	let relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+	let mut relays: Vec<Relay> = convert_db_list(&mut pool_conn, db_relays)?;
+	load_state_for_relays(&mut relays, &app_state).await?;
+
 	Ok(HttpResponse::Ok().json(relays))
 }
 
 #[get("/controllers/{controller_id}/relays/{relay_num}")]
 pub async fn show_for_controller(
 	pool: web::Data<Pool<Sqlite>>,
+	app_state: web::Data<Addr<AppState>>,
 	path: web::Path<(String, i64)>,
 ) -> Result<HttpResponse, EmgauwaError> {
 	let mut pool_conn = pool.acquire().await?;
@@ -75,12 +100,14 @@ pub async fn show_for_controller(
 		.await?
 		.ok_or(DatabaseError::NotFound)?;
 
-	let relay = DbRelay::get_by_controller_and_num(&mut pool_conn, &controller, relay_num)
+	let db_relay = DbRelay::get_by_controller_and_num(&mut pool_conn, &controller, relay_num)
 		.await?
 		.ok_or(DatabaseError::NotFound)?;
 
-	let return_relay = Relay::from_db_model(&mut pool_conn, relay)?;
-	Ok(HttpResponse::Ok().json(return_relay))
+	let mut relay = Relay::from_db_model(&mut pool_conn, db_relay)?;
+	load_state_for_relay(&mut relay, &app_state).await?;
+
+	Ok(HttpResponse::Ok().json(relay))
 }
 
 #[put("/controllers/{controller_id}/relays/{relay_num}")]
@@ -131,17 +158,16 @@ pub async fn update_for_controller(
 
 	let mut return_relay = Relay::from_db_model(&mut pool_conn, relay)?;
 
+	load_state_for_relay(&mut return_relay, &app_state).await?;
 	match &data.override_schedule {
 		Some(Some(s_uid)) => { // We want to set an override schedule
 			let schedule = s_uid.get_schedule(&mut pool_conn).await?;
-			return_relay.override_schedule = Some(Some(schedule));
+			return_relay.override_schedule = Some(schedule);
 		}
 		Some(None) => { // We want to unset the override schedule
-			return_relay.override_schedule = Some(None);
-		}
-		None => { // We want to keep the override schedule as is
 			return_relay.override_schedule = None;
 		}
+		None => {} // We want to keep the override schedule as is
 	}
 
 	app_state