use std::time::Duration;
use crate::helpers::{first_positional, has_flag, parse_u64_option, parse_usize_option};
use super::load_status_snapshot;
use super::info::action_matches;
pub(super) fn action_watch(args: &[String]) -> Result<(), String> {
let json = has_flag(args, "--json");
let iterations = parse_usize_option(args, "--iterations", 1)?;
let interval_ms = parse_u64_option(args, "--interval-ms", 1000)?;
let action_name = first_positional(args);
let mut snapshots = Vec::new();
let mut source_meta = serde_json::json!({"mode": "unknown"});
let mut source_label = String::from("unknown");
let mut latest_captured_at_unix_nanos = 0u128;
for idx in 0..iterations {
let (snapshot, source) = load_status_snapshot(args)?;
source_meta = source.json;
source_label = source.label;
latest_captured_at_unix_nanos = snapshot.captured_at_unix_nanos;
let actions = snapshot
.actions
.iter()
.filter(|action| {
action_name
.as_ref()
.map(|name| action_matches(&action.name, name))
.unwrap_or(true)
})
.cloned()
.collect::<Vec<_>>();
snapshots.push(serde_json::json!({
"iteration": idx + 1,
"captured_at_unix_nanos": snapshot.captured_at_unix_nanos,
"actions": actions,
}));
if idx + 1 < iterations {
std::thread::sleep(Duration::from_millis(interval_ms));
}
}
if json {
let payload = serde_json::json!({
"api_version": "robotrt.action.watch.v1",
"kind": "action_watch",
"captured_at_unix_nanos": latest_captured_at_unix_nanos,
"source": source_meta,
"query": {
"action_name": action_name,
"iterations": iterations,
"interval_ms": interval_ms,
},
"result": {
"samples": snapshots,
},
});
println!(
"{}",
serde_json::to_string_pretty(&payload)
.map_err(|err| format!("serialize action watch failed: {err}"))?
);
} else {
println!("RobotRT Action Watch");
println!("source: {}", source_label);
for snapshot in snapshots {
println!("{}", snapshot);
}
}
Ok(())
}
pub(super) fn mission_watch(args: &[String]) -> Result<(), String> {
let json = has_flag(args, "--json");
let iterations = parse_usize_option(args, "--iterations", 1)?;
let interval_ms = parse_u64_option(args, "--interval-ms", 1000)?;
let mission_name = first_positional(args);
let mut snapshots = Vec::new();
let mut source_meta = serde_json::json!({"mode": "unknown"});
let mut source_label = String::from("unknown");
let mut latest_captured_at_unix_nanos = 0u128;
for idx in 0..iterations {
let (snapshot, source) = load_status_snapshot(args)?;
source_meta = source.json;
source_label = source.label;
latest_captured_at_unix_nanos = snapshot.captured_at_unix_nanos;
let missions = snapshot
.missions
.iter()
.filter(|mission| {
mission_name
.as_ref()
.map(|name| mission.name == *name)
.unwrap_or(true)
})
.cloned()
.collect::<Vec<_>>();
snapshots.push(serde_json::json!({
"iteration": idx + 1,
"captured_at_unix_nanos": snapshot.captured_at_unix_nanos,
"missions": missions,
}));
if idx + 1 < iterations {
std::thread::sleep(Duration::from_millis(interval_ms));
}
}
if json {
let payload = serde_json::json!({
"api_version": "robotrt.mission.watch.v1",
"kind": "mission_watch",
"captured_at_unix_nanos": latest_captured_at_unix_nanos,
"source": source_meta,
"query": {
"mission_name": mission_name,
"iterations": iterations,
"interval_ms": interval_ms,
},
"result": {
"samples": snapshots,
},
});
println!(
"{}",
serde_json::to_string_pretty(&payload)
.map_err(|err| format!("serialize mission watch failed: {err}"))?
);
} else {
println!("RobotRT Mission Watch");
println!("source: {}", source_label);
for snapshot in snapshots {
println!("{}", snapshot);
}
}
Ok(())
}