firecloud-cli 0.2.0

Command-line interface for FireCloud P2P messaging and file sharing
//! FireCloud CLI - Distributed Storage Network
//!
//! Simple Commands:
//! - `firecloud setup` - First-time setup
//! - `firecloud upload <file>` - Upload a file  
//! - `firecloud download` - Download files (interactive)
//! - `firecloud network` - View network topology
//! - `firecloud usage` - Storage provider dashboard
//! - `firecloud mod` - Modify provider settings

use anyhow::Result;
use clap::{Parser, Subcommand};
use directories::ProjectDirs;
use std::path::PathBuf;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

mod commands;
mod config;
mod format;
mod password;
mod ui;

pub use config::FireCloudConfig;

#[derive(Parser)]
#[command(name = "firecloud")]
#[command(author, version, about = "Decentralized, local-first cloud storage")]
struct Cli {
    /// Enable verbose logging
    #[arg(short, long, global = true)]
    verbose: bool,

    /// Data directory (default: ~/.local/share/firecloud)
    #[arg(short, long, global = true)]
    data_dir: Option<PathBuf>,

    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// First-time setup - Initialize FireCloud on your device
    Setup,

    /// Upload a file to the network
    Upload {
        /// Path to the file to upload
        file: PathBuf,
    },

    /// Download files from the network (interactive)
    Download {
        /// Optional: Specify file ID to download directly
        #[arg(short, long)]
        file_id: Option<String>,
    },

    /// View network topology and statistics
    Network {
        /// Enable live updating view
        #[arg(short, long)]
        live: bool,
    },

    /// Storage provider dashboard (view usage statistics)
    Usage,

    /// Modify storage provider settings
    Mod,
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = Cli::parse();

    // Initialize logging
    let log_level = if cli.verbose { "debug" } else { "info" };

    tracing_subscriber::registry()
        .with(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| format!("firecloud={},libp2p=warn", log_level).into()),
        )
        .with(tracing_subscriber::fmt::layer())
        .init();

    // Determine data directory
    let default_data_dir = cli.data_dir.clone().unwrap_or_else(|| {
        ProjectDirs::from("io", "firecloud", "firecloud")
            .map(|dirs| dirs.data_dir().to_path_buf())
            .unwrap_or_else(|| PathBuf::from(".firecloud"))
    });

    let data_dir = default_data_dir.clone();

    match cli.command {
        Commands::Setup => {
            commands::setup::run(data_dir).await?;
        }
        Commands::Upload { file } => {
            commands::upload::run(data_dir, file).await?;
        }
        Commands::Download { file_id } => {
            commands::download_interactive::run_interactive(data_dir, file_id).await?;
        }
        Commands::Network { live } => {
            commands::network::run(data_dir, live).await?;
        }
        Commands::Usage => {
            commands::usage::run(data_dir).await?;
        }
        Commands::Mod => {
            commands::mod_provider::run(data_dir).await?;
        }
    }

    Ok(())
}