use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use runar_common::logging::{Component, Logger};
use std::path::PathBuf;
use std::sync::Arc;
mod config;
mod init;
mod key_store;
mod setup_server;
mod start;
use init::InitCommand;
use start::StartCommand;
#[derive(Parser)]
#[command(name = "runar")]
#[command(about = "Runar Node CLI - Initialize and manage Runar nodes")]
#[command(version = env!("CARGO_PKG_VERSION"))]
struct Cli {
#[command(subcommand)]
command: Option<Commands>,
#[arg(short, long)]
verbose: bool,
#[arg(short, long)]
config_dir: Option<PathBuf>,
}
#[derive(Subcommand)]
enum Commands {
#[command(name = "init")]
Init {
#[arg(short, long)]
force: bool,
},
#[command(name = "start")]
Start {
#[arg(short, long)]
config: Option<PathBuf>,
},
}
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
let cli = Cli::parse();
let logger = Arc::new(Logger::new_root(Component::CLI, "main"));
let config_dir = cli.config_dir.unwrap_or_else(|| {
dirs::home_dir()
.expect("Could not determine home directory")
.join(".runar")
});
std::fs::create_dir_all(&config_dir)
.with_context(|| format!("Failed to create config directory: {config_dir:?}"))?;
match cli.command {
Some(Commands::Init { force }) => {
let init_cmd = InitCommand::new(config_dir, logger.clone());
init_cmd.run(force).await?;
}
Some(Commands::Start { config }) => {
let start_cmd = StartCommand::new(config_dir, logger.clone());
start_cmd.run(config).await?;
}
None => {
let config_file = config_dir.join("config.json");
if config_file.exists() {
println!("Configuration found. Use 'runar start' to start the node.");
println!("Use 'runar init --force' to re-initialize.");
} else {
println!("No configuration found. Use 'runar init' to initialize a new node.");
}
}
}
Ok(())
}