firecloud-cli 0.2.0

Command-line interface for FireCloud P2P messaging and file sharing
//! Status command - Show network status and statistics

use anyhow::Result;
use firecloud_net::{FireCloudNode, NodeConfig, NodeEvent};
use firecloud_storage::{ChunkStore, ManifestStore};
use std::path::PathBuf;
use std::time::{Duration, Instant};

pub async fn run(data_dir: PathBuf) -> Result<()> {
    println!("FireCloud Network Status");
    println!("========================\n");

    // Show storage stats
    let chunk_store_path = data_dir.join("chunks");
    let manifest_store_path = data_dir.join("manifests");

    if chunk_store_path.exists() {
        let chunk_store = ChunkStore::open(&chunk_store_path)?;
        let chunk_count = chunk_store.count()?;
        let chunk_size = chunk_store.total_size()?;
        println!("📦 Local Storage:");
        println!("   Chunks: {} ({:.2} MB)", chunk_count, chunk_size as f64 / 1024.0 / 1024.0);
    }

    if manifest_store_path.exists() {
        let manifest_store = ManifestStore::open(&manifest_store_path)?;
        let files = manifest_store.list()?;
        println!("   Files:  {} manifests", files.len());
    }

    println!();

    // Network discovery
    println!("🌐 Network Discovery (scanning for 5 seconds)...\n");

    let config = NodeConfig {
        port: 0,
        enable_mdns: true,
        bootstrap_peers: Vec::new(),
        bootstrap_relays: vec![],
    };

    let mut node = FireCloudNode::new(config).await?;
    let local_peer = node.local_peer_id();

    println!("   Local Peer ID: {}", local_peer);

    let start = Instant::now();
    let discovery_duration = Duration::from_secs(5);
    let mut discovered_peers = Vec::new();
    let mut listen_addrs = Vec::new();

    while start.elapsed() < discovery_duration {
        tokio::select! {
            _ = tokio::time::sleep(Duration::from_millis(100)) => {}
            event = node.poll_event() => {
                if let Some(event) = event {
                    match event {
                        NodeEvent::PeerDiscovered(peer) => {
                            if peer != local_peer && !discovered_peers.contains(&peer) {
                                discovered_peers.push(peer);
                            }
                        }
                        NodeEvent::Listening(addr) => {
                            listen_addrs.push(addr);
                        }
                        _ => {}
                    }
                }
            }
        }
    }

    println!("\n   Listen Addresses:");
    for addr in &listen_addrs {
        println!("     - {}", addr);
    }

    println!("\n   Connected Peers: {}", node.connected_peers_count());
    println!("   Kademlia Routing: {} peers", node.kademlia_peers_count());

    if discovered_peers.is_empty() {
        println!("\n   ⚠️  No peers discovered via mDNS");
        println!("   Tip: Run `firecloud node` on another device on the same network");
    } else {
        println!("\n   📡 Discovered Peers ({}):", discovered_peers.len());
        for peer in &discovered_peers {
            println!("     - {}", peer);
        }
    }

    println!();

    // Show tips based on status
    println!("💡 Tips:");
    if discovered_peers.is_empty() {
        println!("   • Start a node on another device: firecloud node --port 4001");
        println!("   • Ensure both devices are on the same local network");
    } else {
        println!("   • Upload a file: firecloud upload <file>");
        println!("   • List files: firecloud list");
        println!("   • Run a persistent node: firecloud node");
    }

    Ok(())
}