use anyhow::Result; use env_logger::Env; use log::{error, info}; use mail2couch::{ cli::parse_command_line, config::Config, sync::SyncCoordinator, }; use std::process; #[tokio::main] async fn main() { // Initialize logging env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); // Parse command line arguments let args = parse_command_line(); // Run the main application if let Err(e) = run(args).await { error!("❌ Application failed: {}", e); process::exit(1); } } async fn run(args: mail2couch::config::CommandLineArgs) -> Result<()> { info!("🚀 Starting mail2couch Rust implementation"); // Load configuration with automatic discovery let (config, config_path) = Config::load_with_discovery(&args)?; info!("Using configuration file: {}", config_path.display()); if let Some(max) = args.max_messages { info!("Maximum messages per mailbox: {}", max); } else { info!("Maximum messages per mailbox: unlimited"); } if args.dry_run { info!("🔍 DRY-RUN MODE: No changes will be made to CouchDB"); } // Display configuration summary print_config_summary(&config); // Create sync coordinator let mut coordinator = SyncCoordinator::new(config, args)?; // Test all connections before starting sync info!("Testing connections..."); coordinator.test_connections().await?; // Perform synchronization info!("Starting synchronization..."); let results = coordinator.sync_all_sources().await?; // Print summary coordinator.print_sync_summary(&results); info!("🎉 mail2couch completed successfully!"); Ok(()) } fn print_config_summary(config: &mail2couch::config::Config) { info!("Configuration summary:"); info!(" CouchDB: {}", config.couch_db.url); info!(" Mail sources: {}", config.mail_sources.len()); for (i, source) in config.mail_sources.iter().enumerate() { let status = if source.enabled { "enabled" } else { "disabled" }; info!( " {}: {} ({}) - {} ({})", i + 1, source.name, source.user, source.host, status ); if source.enabled { if !source.folder_filter.include.is_empty() { info!(" Include folders: {:?}", source.folder_filter.include); } if !source.folder_filter.exclude.is_empty() { info!(" Exclude folders: {:?}", source.folder_filter.exclude); } if source.message_filter.since.is_some() { info!(" Since: {:?}", source.message_filter.since); } if !source.message_filter.subject_keywords.is_empty() { info!(" Subject keywords: {:?}", source.message_filter.subject_keywords); } } } }