mod error;
mod nvd_fetcher;
mod exploit_collector;

use clap::Parser;
use nvd_fetcher::{NvdCveFetcher, FeedType};
use exploit_collector::ExploitCollector;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
    /// Type of NVD feed to download
    #[arg(value_enum, long, default_value_t = FeedType::Recent)]
    feed: FeedType,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Parse command-line arguments
    let cli = Cli::parse();

    // Initialize NVD CVE Fetcher
    let nvd_fetcher = NvdCveFetcher::new()?;

    // Fetch CVEs based on feed type
    let cves = nvd_fetcher.fetch_cves(cli.feed).await?;
    
    println!("Fetched {} CVEs", cves.len());

    // Initialize ExploitCollector
    let collector = ExploitCollector::new()?;

    // Search and collect for each CVE
    for cve_id in cves {
        println!("Searching for repositories related to: {}", cve_id);

        match collector.search_cve_repos(&cve_id).await {
            Ok(repos) => {
                println!("Found {} repositories", repos.len());

                // Save repositories to file
                if let Err(e) = collector.save_repositories(&cve_id, &repos) {
                    eprintln!("Error saving repositories for {}: {}", cve_id, e);
                }

                // Print repository details (optional)
                for repo in &repos {
                    println!("- {}", repo.full_name);
                    println!("  URL: {}", repo.html_url);
                    println!("  Stars: {}", repo.stargazers_count);
                    if let Some(desc) = &repo.description {
                        println!("  Description: {}", desc);
                    }
                    println!();
                }
            }
            Err(e) => {
                eprintln!("Error searching for {}: {}", cve_id, e);
            }
        }
    }

    println!("Collection complete.");
    Ok(())
}
