use crate::bridge::preview_render::{CacheKind, cache_fingerprint};
use indicatrix_vault::{db::sqlite::Database, model::tilt_curves::TiltPerformanceCurves};
use std::{
sync::{Mutex, PoisonError},
time::{SystemTime, UNIX_EPOCH},
};
use tracing::warn;
pub(super) fn save_curves(
db: &Mutex<Database>,
entry_id: i64,
curves: &TiltPerformanceCurves,
material_name: Option<&str>,
expected_updated_at: Option<i64>,
) -> bool {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |d| i64::try_from(d.as_secs()).unwrap_or(i64::MAX));
let fingerprint = cache_fingerprint(CacheKind::TiltCurves, material_name);
let stored = db
.lock()
.unwrap_or_else(PoisonError::into_inner)
.save_tilt_curves(entry_id, curves, now, &fingerprint, expected_updated_at);
match stored {
Ok(true) => true,
Ok(false) => {
warn!(
"Discarded the tilt curves computed for entry {entry_id}: the design changed \
while they were computed"
);
false
}
Err(e) => {
warn!("Failed to save the tilt curves for entry {entry_id}: {e}");
false
}
}
}
#[must_use]
pub fn save_tilt_curves_for_entry(
db: &Mutex<Database>,
entry_id: i64,
curves: &TiltPerformanceCurves,
) -> bool {
let (updated_at, material_name) = {
let guard = db.lock().unwrap_or_else(PoisonError::into_inner);
let Ok(updated_at) = guard.entry_updated_at(entry_id) else {
return false;
};
(
updated_at,
guard.get_preview_material(entry_id).ok().flatten(),
)
};
save_curves(db, entry_id, curves, material_name.as_deref(), updated_at)
}