use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::time::Duration;
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use scopinator_seestar::InteropKey;
mod commands;
#[derive(Parser)]
#[command(name = "scopinator", about = "Telescope control CLI")]
struct Cli {
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,
#[arg(long, env = "SEESTAR_INTEROP_PEM", value_name = "PATH")]
interop_pem: Option<PathBuf>,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Discover {
#[arg(short, long, default_value = "3")]
timeout: u64,
},
Status {
#[arg(short = 'H', long)]
host: Ipv4Addr,
},
Goto {
#[arg(short = 'H', long)]
host: Ipv4Addr,
#[arg(long)]
ra: f64,
#[arg(long)]
dec: f64,
#[arg(short, long, default_value = "Target")]
name: String,
},
Park {
#[arg(short = 'H', long)]
host: Ipv4Addr,
},
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let log_level = match cli.verbose {
0 => "info",
1 => "debug",
_ => "trace",
};
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(log_level)),
)
.init();
let interop_key: Option<InteropKey> = if let Some(path) = &cli.interop_pem {
let pem = std::fs::read_to_string(path)
.with_context(|| format!("failed to read interop PEM from {}", path.display()))?;
let key = InteropKey::from_pem(&pem)
.with_context(|| format!("failed to parse interop PEM from {}", path.display()))?;
Some(key)
} else {
None
};
match cli.command {
Commands::Discover { timeout } => {
commands::discover(Duration::from_secs(timeout)).await?;
}
Commands::Status { host } => {
commands::status(host, interop_key).await?;
}
Commands::Goto {
host,
ra,
dec,
name,
} => {
commands::goto(host, ra, dec, &name, interop_key).await?;
}
Commands::Park { host } => {
commands::park(host, interop_key).await?;
}
}
Ok(())
}