use anyhow::{Result, bail};
use crate::config::Resolved;
use crate::queue::save_queue;
use super::model::RestoreResult;
use super::storage::{
UNDO_SNAPSHOT_PREFIX, list_undo_snapshots, load_undo_snapshot, undo_cache_dir,
};
pub fn restore_from_snapshot(
resolved: &Resolved,
snapshot_id: Option<&str>,
dry_run: bool,
) -> Result<RestoreResult> {
let list = list_undo_snapshots(&resolved.repo_root)?;
if list.snapshots.is_empty() {
bail!("No undo snapshots available");
}
let target_id = snapshot_id
.map(str::to_string)
.unwrap_or_else(|| list.snapshots[0].id.clone());
let snapshot = load_undo_snapshot(&resolved.repo_root, &target_id)?;
let tasks_affected = snapshot.queue_json.tasks.len() + snapshot.done_json.tasks.len();
if dry_run {
return Ok(RestoreResult {
snapshot_id: target_id,
operation: snapshot.operation,
timestamp: snapshot.timestamp,
tasks_affected,
});
}
save_queue(&resolved.done_path, &snapshot.done_json)?;
save_queue(&resolved.queue_path, &snapshot.queue_json)?;
let undo_dir = undo_cache_dir(&resolved.repo_root);
let snapshot_path = undo_dir.join(format!("{}{}.json", UNDO_SNAPSHOT_PREFIX, target_id));
if let Err(err) = std::fs::remove_file(&snapshot_path) {
log::warn!("failed to remove used snapshot: {:#}", err);
}
log::info!(
"restored queue state from snapshot '{}' (operation: {}, {} tasks affected)",
target_id,
snapshot.operation,
tasks_affected
);
Ok(RestoreResult {
snapshot_id: target_id,
operation: snapshot.operation,
timestamp: snapshot.timestamp,
tasks_affected,
})
}