use vta_sdk::client::VtaClient;
use vta_cli_common::render::{GREEN, RED, RESET};
use crate::auth;
use crate::cli::VtaCommands;
use crate::config::{self, PnmConfig};
pub(crate) async fn run_offline(
pnm_config: &mut PnmConfig,
vta_override: Option<&str>,
command: &VtaCommands,
) -> bool {
match command {
VtaCommands::List => {
if pnm_config.vtas.is_empty() {
println!("No VTAs configured.");
println!("\nRun `pnm setup` to configure your first VTA.");
} else {
let default = pnm_config.default_vta.as_deref().unwrap_or("");
for (slug, vta) in &pnm_config.vtas {
let marker = if slug == default { " (default)" } else { "" };
println!(" {slug}{marker}");
println!(" Name: {}", vta.name);
if let Some(ref did) = vta.vta_did {
println!(" DID: {did}");
}
println!();
}
}
true
}
VtaCommands::Use { slug } => {
if !pnm_config.vtas.contains_key(slug) {
eprintln!(
"Error: VTA '{slug}' not found.\n\nConfigured VTAs: {}",
pnm_config
.vtas
.keys()
.cloned()
.collect::<Vec<_>>()
.join(", ")
);
std::process::exit(1);
}
pnm_config.default_vta = Some(slug.clone());
if let Err(e) = config::save_config(pnm_config) {
eprintln!("Error saving config: {e}");
std::process::exit(1);
}
println!("Default VTA set to '{slug}'.");
true
}
VtaCommands::Remove { slug } => {
if !pnm_config.vtas.contains_key(slug) {
eprintln!("Error: VTA '{slug}' not found.");
std::process::exit(1);
}
pnm_config.vtas.remove(slug);
if pnm_config.default_vta.as_deref() == Some(slug.as_str()) {
pnm_config.default_vta = pnm_config.vtas.keys().next().cloned();
}
let key = config::vta_keyring_key(slug);
auth::logout(&key);
if let Err(e) = config::save_config(pnm_config) {
eprintln!("Error saving config: {e}");
std::process::exit(1);
}
println!("VTA '{slug}' removed.");
true
}
VtaCommands::Info => {
match config::resolve_vta(vta_override, pnm_config) {
Ok((slug, vta)) => {
println!("Active VTA: {slug}");
println!(" Name: {}", vta.name);
if let Some(ref did) = vta.vta_did {
println!(" DID: {did}");
if let Ok(url) = vta_sdk::session::resolve_vta_url(did).await {
println!(" URL: {url} (from DID)");
}
}
let key = config::vta_keyring_key(&slug);
auth::status(&key);
}
Err(e) => {
eprintln!("Error: {e}");
std::process::exit(1);
}
}
true
}
VtaCommands::Restart => false,
}
}
pub(crate) async fn run_restart(client: &VtaClient) -> Result<(), Box<dyn std::error::Error>> {
println!("Requesting VTA restart...");
client.restart().await?;
println!("{GREEN}✓{RESET} Restart initiated");
println!("Waiting for VTA to come back...");
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
for attempt in 1..=5 {
match client.health().await {
Ok(resp) => {
let ver = resp.version.as_deref().unwrap_or("?");
println!("{GREEN}✓{RESET} VTA is back (v{ver})");
return Ok(());
}
Err(_) if attempt < 5 => {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
}
Err(e) => {
println!("{RED}✗{RESET} VTA did not come back after restart: {e}");
println!(" The VTA may still be restarting. Try `pnm health` in a few seconds.");
}
}
}
Ok(())
}