use std::collections::BTreeMap;
use std::path::Path;
use shep_client::shep_core::config::AppConfig;
use crate::daemon::Daemon;
use crate::error::Error;
use crate::paths::Tree;
pub(super) enum PutBack {
Done,
Untouched(Error),
Reset(Error),
PartlyDeleted(Error),
Deleted(Error),
}
pub(super) async fn put_back<D: Daemon>(
daemon: &D,
sheep: &str,
registered: &BTreeMap<String, AppConfig>,
origin: Option<&AppConfig>,
cwd: &Path,
script: &str,
) -> PutBack {
let Some(current) = registered.get(sheep).cloned() else {
return PutBack::Untouched(Error::Config(format!(
"{sheep} is no longer registered, so there is nothing to put back"
)));
};
let restored = match origin {
Some(origin) => {
let mut restored = origin.clone();
restored.name = sheep.to_owned();
restored
.cwd
.get_or_insert_with(|| cwd.display().to_string());
restored
}
None => {
let mut restored = current.clone();
restored.cwd = Some(cwd.display().to_string());
restored.script = script.to_owned();
restored
}
};
let live = match daemon.describe(sheep).await {
Ok(live) => live,
Err(err) => return PutBack::Untouched(err),
};
let mut any_delete_landed = false;
for info in &live {
if let Err(err) = daemon.delete(info.id).await {
return if any_delete_landed {
PutBack::PartlyDeleted(err)
} else {
PutBack::Untouched(err)
};
}
any_delete_landed = true;
}
match daemon.start(vec![restored]).await {
Ok(_) => PutBack::Done,
Err(err) => {
if daemon.start(vec![current]).await.is_ok() {
PutBack::Reset(err)
} else {
PutBack::Deleted(err)
}
}
}
}
pub(super) fn registered_against(
registered: &BTreeMap<String, AppConfig>,
sheep: &str,
tree: &Tree,
) -> bool {
registered
.get(sheep)
.and_then(|app| app.cwd.as_deref())
.is_some_and(|cwd| crate::shared::same_path(Path::new(cwd), &tree.current()))
}