use crate::monitor::{ConnectionStatus, NetworkStats};
use clap::Parser;
#[derive(Parser, Debug)]
#[command(name = "hale")]
#[command(about = "Instant network connection quality monitor")]
#[command(version)]
pub struct Cli {
#[arg(short = 'c', long = "check")]
pub check: bool,
#[arg(short, long, default_value = "text")]
pub format: OutputFormat,
#[arg(short, long)]
pub verbose: bool,
}
#[derive(Debug, Clone, Default, clap::ValueEnum)]
pub enum OutputFormat {
#[default]
Text,
Json,
}
pub fn parse_args() -> Cli {
Cli::parse()
}
pub fn display_cli_stats(stats: &NetworkStats, format: &OutputFormat, verbose: bool) {
match format {
OutputFormat::Text => {
display_text_format(stats, verbose);
}
OutputFormat::Json => {
display_json_format(stats);
}
}
}
fn display_text_format(stats: &NetworkStats, verbose: bool) {
let (symbol, color_code, status_text) = match stats.status {
ConnectionStatus::Ok => ("✓", "\x1b[32m", "OK"), ConnectionStatus::Slow => ("⚠", "\x1b[33m", "Slow"), ConnectionStatus::Disconnected => ("✗", "\x1b[31m", "DISCONNECTED"), };
let latency_display = if stats.avg_latency_ms > 0.0 {
format!("{:.0}ms", stats.avg_latency_ms)
} else {
"timeout".to_string()
};
println!(
"{}{} {} {}\x1b[0m",
color_code, symbol, status_text, latency_display
);
if stats.status != ConnectionStatus::Ok {
let reason = match stats.status {
ConnectionStatus::Slow => format!(" High latency ({:.0}ms)", stats.avg_latency_ms),
ConnectionStatus::Disconnected => {
if stats.avg_latency_ms > 0.0 {
format!(" Very high latency ({:.0}ms)", stats.avg_latency_ms)
} else {
" No response from network".to_string()
}
}
_ => String::new(),
};
if !reason.is_empty() {
println!("{}", reason);
}
}
if verbose {
println!(
" Timestamp: {}",
stats.timestamp.format("%Y-%m-%d %H:%M:%S")
);
}
}
fn display_json_format(stats: &NetworkStats) {
println!(
r#"{{"timestamp":"{}","status":"{}","latency_ms":{:.1}}}"#,
stats.timestamp.to_rfc3339(),
stats.status,
stats.avg_latency_ms
);
}
pub fn get_exit_code(status: ConnectionStatus) -> i32 {
match status {
ConnectionStatus::Ok => 0,
ConnectionStatus::Slow | ConnectionStatus::Disconnected => 1,
}
}