use std::path::{Path, PathBuf};
use bestool_canopy::registration;
use bestool_tamanu::server_info::{
standard_device_key_path, standard_server_id_path, standard_tags_path,
};
use clap::Parser;
use miette::{IntoDiagnostic as _, Result, WrapErr as _};
use crate::actions::Context;
#[derive(Debug, Clone, Parser)]
pub struct UnregisterArgs {
#[arg(long, value_name = "DIR")]
pub config: Option<PathBuf>,
#[arg(long, short = 'y')]
pub yes: bool,
}
pub async fn run(args: UnregisterArgs, _ctx: Context) -> Result<()> {
let UnregisterArgs { config, yes } = args;
let dir = config.unwrap_or_else(registration::default_dir);
let tags_path = dir.join("tags.json");
super::ensure_writable_or_reexec(&dir)?;
if !yes && !confirm(&dir, &tags_path)? {
println!("Aborted; nothing was removed.");
return Ok(());
}
let mut removed = Vec::new();
if registration::delete_in(&dir)
.await
.wrap_err("removing canopy registration")?
{
removed.push(format!("canopy registration ({})", dir.display()));
}
removed.extend(super::clear_legacy_identity(&tags_path).await);
if removed.is_empty() {
println!("No canopy enrolment found; nothing to remove.");
} else {
println!("Removed:");
for item in &removed {
println!(" {item}");
}
}
super::restart_daemon_for_registration_change().await;
Ok(())
}
fn confirm(dir: &Path, tags_path: &Path) -> Result<bool> {
use std::io::Write as _;
println!("This erases this host's canopy enrolment from:");
println!(" canopy registration ({})", dir.display());
println!(" {}", standard_device_key_path().display());
println!(" {}", standard_server_id_path().display());
println!(" {} (cached tags)", tags_path.display());
println!(" {} (legacy cached tags)", standard_tags_path().display());
println!(" deviceKey/metaServerId rows in the Tamanu database (if reachable)");
print!("Proceed? [y/N] ");
std::io::stdout().flush().into_diagnostic()?;
let mut line = String::new();
std::io::stdin().read_line(&mut line).into_diagnostic()?;
Ok(matches!(
line.trim().to_ascii_lowercase().as_str(),
"y" | "yes"
))
}