use std::io::{self, Write};
use tracing::info;
use super::try_connect_daemon;
pub async fn pause_alert(
alert_path: &str,
until: Option<&str>,
addrs: &[std::net::SocketAddr],
) -> miette::Result<()> {
let until_timestamp = if let Some(until_str) = until {
if let Ok(ts) = until_str.parse::<jiff::Timestamp>() {
ts
} else {
let span: jiff::Span = until_str
.parse()
.map_err(|e| miette::miette!("failed to parse time '{}': {}", until_str, e))?;
jiff::Timestamp::now()
.checked_add(span)
.map_err(|e| miette::miette!("time calculation overflow: {}", e))?
}
} else {
jiff::Timestamp::now()
.checked_add(jiff::Span::new().days(7))
.map_err(|e| miette::miette!("time calculation overflow: {}", e))?
};
let (client, base_url) = try_connect_daemon(addrs).await?;
let url = format!("{}/alerts", base_url);
let body = serde_json::json!({
"alert": alert_path,
"until": until_timestamp.to_string(),
});
let response = client
.delete(&url)
.json(&body)
.send()
.await
.map_err(|e| miette::miette!("failed to send pause request: {}", e))?;
if response.status() == reqwest::StatusCode::NOT_FOUND {
info!("alert not found, trying to find partial match");
let alerts_response = client
.get(format!("{}/alerts", base_url))
.send()
.await
.map_err(|e| miette::miette!("failed to get alerts list: {}", e))?;
let alerts: Vec<String> = alerts_response
.json()
.await
.map_err(|e| miette::miette!("failed to parse alerts list: {}", e))?;
let matches: Vec<&String> = alerts.iter().filter(|a| a.contains(alert_path)).collect();
if matches.is_empty() {
return Err(miette::miette!(
"alert '{}' not found and no partial matches",
alert_path
));
} else if matches.len() == 1 {
println!("Alert '{}' not found.", alert_path);
println!("Did you mean: {}", matches[0]);
print!("Pause this alert? [y/N] ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.map_err(|e| miette::miette!("failed to read input: {}", e))?;
if input.trim().eq_ignore_ascii_case("y") || input.trim().eq_ignore_ascii_case("yes") {
let retry_url = format!("{}/alerts", base_url);
let retry_body = serde_json::json!({
"alert": matches[0],
"until": until_timestamp.to_string(),
});
let retry_response = client
.delete(&retry_url)
.json(&retry_body)
.send()
.await
.map_err(|e| miette::miette!("failed to send pause request: {}", e))?;
if !retry_response.status().is_success() {
return Err(miette::miette!(
"failed to pause alert (status: {})",
retry_response.status()
));
}
println!("Alert paused until {}", until_timestamp);
return Ok(());
} else {
return Err(miette::miette!("pause cancelled"));
}
} else {
println!(
"Alert '{}' not found. Did you mean one of these?",
alert_path
);
for (i, m) in matches.iter().enumerate() {
println!(" {}. {}", i + 1, m);
}
return Err(miette::miette!(
"multiple matches found, please be more specific"
));
}
}
if !response.status().is_success() {
return Err(miette::miette!(
"failed to pause alert (status: {})",
response.status()
));
}
println!("Alert paused until {}", until_timestamp);
Ok(())
}