use anyhow::{anyhow, Result};
use clap::Parser;
use tracing_appender::rolling;
use tracing_subscriber::EnvFilter;
use huddle_core::network::NetworkMode;
mod app;
mod input;
mod ui;
#[derive(Parser)]
#[command(name = "huddle", version, about = "Huddle — decentralized encrypted chat (TUI)")]
struct Cli {
#[arg(long, help = "Override data directory")]
data_dir: Option<String>,
#[arg(long, value_parser = parse_mode)]
mode: Option<NetworkMode>,
#[arg(long, default_value_t = 0u16)]
port: u16,
}
fn parse_mode(s: &str) -> std::result::Result<NetworkMode, String> {
NetworkMode::from_str(s).ok_or_else(|| format!("unknown mode `{s}` (try mdns or direct)"))
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let log_path = huddle_core::config::log_path();
if let Some(parent) = log_path.parent() {
std::fs::create_dir_all(parent)?;
}
let file_appender = rolling::never(
log_path.parent().unwrap(),
log_path.file_name().unwrap(),
);
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env().add_directive("huddle=debug".parse()?))
.with_writer(file_appender)
.with_ansi(false)
.init();
let mode = cli.mode.unwrap_or(NetworkMode::Mdns);
if cli.mode.is_none() && !app::show_welcome()? {
return Ok(());
}
let handle = huddle_core::app::AppHandle::start_with_options(mode, cli.port)
.await
.map_err(|e| anyhow!(e))?;
app::run_tui(handle).await
}