Skip to main content

Air/
Binary.rs

1//! # Air Binary Entry Point
2//!
3//! ## Overview
4//!
5//! Air 🪁 is the persistent background daemon that handles resource-intensive
6//! operations for the Land code editor. It runs as a standalone process
7//! alongside Mountain, communicating via the Vine (gRPC) protocol to offload
8//! tasks like updates, downloads, authentication, and file indexing.
9//!
10//! ## Architecture & Connections
11//!
12//! Air serves as the background services hub in the Land ecosystem:
13//!
14//! - **Wind** (Effect-TS): Provides functional programming patterns and
15//!   type-safe effects that Air uses for predictable state management and error
16//!   handling
17//!
18//! - **Cocoon** (NodeJS host): The Node.js runtime environment for frontend/web
19//!   components. Air coordinates with Cocoon through the Vine protocol to
20//!   deliver web assets and perform frontend build operations. Uses port 50052.
21//!
22//! - **Mountain** (Tauri bundler): The main desktop application bundle that
23//!   packages the Rust backend with the Electron/Node.js frontend. Mountain
24//!   receives work from Air through Vine (gRPC) and orchestrates the bundling
25//!   process.
26//!
27//! - **Vine** (gRPC protocol): The communication layer connecting all
28//!   components. Air hosts the Vine gRPC server on port 50053, receiving
29//!   requests from Mountain and responding with results from background
30//!   operations.
31//!
32//! ## VSCode Architecture References
33//!
34//! Air's architecture draws inspiration from VSCode's background service model:
35//!
36//! - **Update Service**: Reference
37//!   `Microsoft/Dependency/Editor/src/vs/platform/update`
38//!   - AbstractUpdateService: Base class for platform-specific update handling
39//!   - UpdateService: Manages update checks, downloads, and installations
40//!   - Similar to Air's UpdateManager component
41//!
42//! - **Lifecycle Management**: Reference
43//!   `Microsoft/Dependency/Editor/src/vs/base/common/lifecycle`
44//!   - Disposable pattern for resource cleanup
45//!   - Event emission and handling
46//!   - Graceful shutdown coordination similar to Air's shutdown logic
47//!
48//! - **Background Services**: VSCode's extension host and language server model
49//!   - Independent processes with IPC communication
50//!   - Health monitoring and automatic restart
51//!   - Similar to Air's daemon management approach
52//!
53//! ## Core Responsibilities
54//!
55//! ### 1. gRPC Server (Vine Protocol)
56//! - Hosts the Vine gRPC server on port 50053
57//! - Receives work requests from Mountain
58//! - Streams results and progress updates
59//! - Manages connection lifecycle and cleanup
60//! - Handles multiple concurrent connections
61//!
62//! ### 2. Authentication Service
63//! - Manages user authentication tokens
64//! - Handles cryptographic operations (signing, encryption)
65//! - Token refresh and validation
66//! - Secure storage management
67//!
68//! ### 3. Update Management
69//! - Checks for application updates
70//! - Downloads update packages
71//! - Verifies checksums and signatures
72//! - Coordinates update installation with Mountain
73//!
74//! ### 4. Download Manager
75//! - Downloads extensions and dependencies
76//! - Resumable downloads with retry logic
77//! - Bandwidth management and throttling
78//! - Progress tracking and reporting
79//!
80//! ### 5. File Indexing
81//! - Background file system scanning
82//! - Maintains searchable index
83//! - Supports code navigation features
84//! - Incremental updates and change detection
85//!
86//! ### 6. Resource Monitoring
87//! - CPU and memory usage tracking
88//! - Connection pool management
89//! - Background task lifecycle
90//! - Performance metrics collection
91//!
92//! ## Protocol Details
93//!
94//! **Vine Protocol (gRPC)**
95//! - Version: 1
96//! - Port: 50053 (Air), 50052 (Cocoon)
97//! - Transport: HTTP/2 with TLS (optional)
98//! - Serialization: Protocol Buffers
99//!
100//! ### Protocol Messages
101//! - `DownloadRequest`: Request to download a file/extension
102//! - `DownloadResponse`: Progress updates and completion
103//! - `AuthRequest`: Authentication/token operations
104//! - `AuthResponse`: Token data and status
105//! - `UpdateRequest`: Update check and download
106//! - `UpdateResponse`: Update availability and progress
107//! - `IndexRequest`: File indexing operations
108//! - `IndexResponse`: Index status and results
109//! - `HealthRequest`: Health check queries
110//! - `HealthResponse`: Service health and metrics
111//!
112//! ## FUTURE Enhancements
113//!
114//! ### High Priority
115//! - [ ] Complete CLI command implementations (all placeholders)
116//! - [ ] Add TLS/mTLS support for gRPC connections
117//! - [ ] Implement connection authentication/authorization
118//! - [ ] Add metrics endpoint (/metrics) HTTP server
119//! - [ ] Implement proper configuration hot-reload
120//! - [ ] Add comprehensive integration tests
121//!
122//! ### Medium Priority
123//! - [ ] Add prometheus metrics export (currently partial)
124//! - [ ] Implement grace period for shutdown (pending operations)
125//! - [ ] Add connection rate limiting
126//! - [ ] Implement request prioritization
127//! - [ ] Add audit logging for sensitive operations
128//! - [ ] Implement plugin/hot-reload system
129//!
130//! ### Low Priority
131//! - [ ] Add structured logging with correlation IDs
132//! - [ ] Implement distributed tracing integration
133//! - [ ] Add health check endpoint for load balancers
134//! - [ ] Implement connection pooling optimizations
135//! - [ ] Add telemetry/observability export
136//! - [ ] Implement A/B testing for features
137//! ## Error Handling Strategy
138//!
139//! All public functions use defensive coding:
140//! - Input validation with descriptive errors
141//! - Timeout handling with cancellation
142//! - Resource cleanup via Drop and explicit cleanup
143//! - Circuit breaker for external dependencies
144//! - Retry logic with exponential backoff
145//! - Metrics recording for all operations
146//!
147//! ## Shutdown Sequence
148//!
149//! 1. Accept shutdown signal (SIGTERM, SIGINT)
150//! 2. Stop accepting new requests
151//! 3. Wait for in-flight requests (with timeout)
152//! 4. Stop background services
153//! 5. Cancel pending background tasks
154//! 6. Release daemon lock
155//! 7. Log final statistics
156//! 8. Exit cleanly
157//!
158//! ## Port Allocation
159//!
160//! - **50052**: Cocoon (NodeJS host) - Frontend/web services
161//! - **50053**: Air (this daemon) - Background services
162//! - **50054**: Reserved for future use (e.g., SideCar service)
163//! - **50055**: Reserved for future metrics endpoints
164
165#![allow(non_snake_case)]
166
167use std::{env, net::SocketAddr, sync::Arc, time::Duration};
168
169use AirLibrary::dev_log;
170use tokio::{signal, time::interval};
171// Import types from AirLibrary (the crate root)
172use AirLibrary::{
173	ApplicationState::ApplicationState,
174	Authentication::AuthenticationService,
175	CLI::{CliParser, Command, ConfigCommand, DebugCommand, OutputFormatter},
176	Configuration::{AirConfiguration, ConfigurationManager},
177	Daemon::DaemonManager,
178	DefaultBindAddress,
179	DefaultConfigFile,
180	Downloader::DownloadManager,
181	HealthCheck::{HealthCheckLevel, HealthCheckManager, HealthStatistics},
182	Indexing::FileIndexer,
183	Logging,
184	Metrics,
185	ProtocolVersion,
186	Tracing,
187	Updates::UpdateManager,
188	VERSION,
189	Vine::Generated::air::air_service_server::AirServiceServer,
190	Vine::Server::AirVinegRPCService::AirVinegRPCService,
191};
192
193// =============================================================================
194// Debug Helpers
195// =============================================================================
196
197/// Logs a checkpoint message at lifecycle level with context tracking
198macro_rules! Trace {
199    ($($arg:tt)*) => {{
200        dev_log!("lifecycle", $($arg)*);
201    }};
202}
203
204/// Shutdown signal handler for graceful termination
205///
206/// This function waits for either Ctrl+C (SIGINT) or SIGTERM signals
207/// and then initiates the shutdown sequence. It provides a timeout
208/// to handle cases where signal handlers fail to install properly.
209///
210/// # FUTURE Enhancements
211/// - Add configurable shutdown timeout (currently infinite)
212/// - Implement signal handling for SIGHUP (reload config)
213/// - Add Windows-specific signal handling beyond Ctrl+C
214/// - Implement graceful timeout with pending operation completion
215async fn WaitForShutdownSignal() {
216	dev_log!("lifecycle", "[Shutdown] Waiting for termination signal...");
217
218	let ctrl_c = async {
219		match signal::ctrl_c().await {
220			Ok(()) => dev_log!("lifecycle", "[Shutdown] Received Ctrl+C signal"),
221			Err(e) => dev_log!("lifecycle", "error: [Shutdown] Failed to install Ctrl+C handler: {}", e),
222		}
223	};
224
225	#[cfg(unix)]
226	let terminate = async {
227		match signal::unix::signal(signal::unix::SignalKind::terminate()) {
228			Ok(mut sig) => {
229				sig.recv().await;
230				dev_log!("lifecycle", "[Shutdown] Received SIGTERM signal");
231			},
232			Err(e) => dev_log!("lifecycle", "error: [Shutdown] Failed to install signal handler: {}", e),
233		}
234	};
235
236	#[cfg(not(unix))]
237	let terminate = std::future::pending::<()>();
238
239	tokio::select! {
240		_ = ctrl_c => {},
241		_ = terminate => {},
242	}
243
244	dev_log!("lifecycle", "[Shutdown] Signal received, initiating graceful shutdown");
245}
246
247/// Initialize logging based on environment variables
248///
249/// Sets up structured logging with support for JSON output (useful for
250/// production) and file-based logging (useful for debugging). Environment
251/// variables:
252///
253/// - `AIR_LOG_JSON`: "true" enables JSON formatted output
254/// - `AIR_LOG_LEVEL`: Set logging level (debug, info, warn, error)
255/// - `AIR_LOG_FILE`: Path to log file (optional)
256///
257/// # FUTURE Enhancements
258/// - Add log rotation support
259/// - Implement log file size limits
260/// - Add structured log correlation IDs
261/// - Support syslog integration on Unix
262/// - Add Windows Event Log integration
263fn InitializeLogging() {
264	// Validate environment variables
265	let json_output = match std::env::var("AIR_LOG_JSON") {
266		Ok(val) if !val.is_empty() => {
267			let normalized = val.to_lowercase();
268			if normalized != "true" && normalized != "false" {
269				eprintln!(
270					"Warning: Invalid AIR_LOG_JSON value '{}', expected 'true' or 'false'. Using default: false",
271					val
272				);
273				false
274			} else {
275				normalized == "true"
276			}
277		},
278		Ok(_) => false,
279		Err(_) => false,
280	};
281
282	// Validate log file path exists and is writable
283	let log_file_path = std::env::var("AIR_LOG_FILE").ok().and_then(|path| {
284		if path.is_empty() {
285			None
286		} else {
287			// Check if directory exists for the log file
288			if let Some(parent) = std::path::PathBuf::from(&path).parent() {
289				if parent.as_os_str().is_empty() {
290					// No parent directory, use current directory
291					Some(path)
292				} else if parent.exists() {
293					Some(path)
294				} else {
295					eprintln!(
296						"Warning: Log file directory does not exist: {}. Logging to stdout only.",
297						parent.display()
298					);
299					None
300				}
301			} else {
302				Some(path)
303			}
304		}
305	});
306
307	// Initialize structured logging with defensive error handling
308	let log_result = Logging::InitializeLogger(json_output, log_file_path.clone());
309
310	match log_result {
311		Ok(_) => {
312			let log_info = match &log_file_path {
313				Some(path) => format!("file: {}", path),
314				None => "stdout/stderr".to_string(),
315			};
316			dev_log!(
317				"lifecycle",
318				"[Boot] Logging initialized - JSON: {}, Output: {}",
319				json_output,
320				log_info
321			);
322		},
323		Err(e) => {
324			// Fallback: ensure we can at least log errors to stderr
325			eprintln!("[ERROR] Failed to initialize structured logging: {}", e);
326			eprintln!("[ERROR] Logging will fall back to stderr-only output");
327		},
328	}
329}
330
331/// Parse command line arguments into daemon config or CLI command
332///
333/// Handles two modes of operation:
334/// 1. CLI mode: Execute commands like `status`, `restart`, `config`, etc.
335/// 2. Daemon mode: Start the background service with optional config/bind args
336///
337/// # Arguments
338///
339/// Returns a tuple of (config_path, bind_address, optional_command)
340/// - If `command` is Some, daemon startup should be skipped
341/// - Otherwise, start daemon with provided config path and bind address
342///
343/// # FUTURE Enhancements
344/// - Add validation for bind address format
345/// - Add validation for config file exists/readable
346/// - Support `--validate-config` flag to check config without starting
347/// - Add `--daemon` flag to force daemon mode with CLI commands
348/// - Make flags case-insensitive
349fn ParseArguments() -> (Option<String>, Option<String>, Option<Command>) {
350	// Defensive: Ensure args collection is not extremely large
351	let args:Vec<String> = std::env::args().collect();
352
353	// Safety: Limit argument length to prevent potential DoS
354	if args.len() > 1024 {
355		eprintln!("[ERROR] Too many command line arguments (max: 1024)");
356		std::process::exit(1);
357	}
358
359	// Safety: Validate each argument length
360	for (i, arg) in args.iter().enumerate() {
361		if arg.len() > 4096 {
362			eprintln!("[ERROR] Argument at position {} is too long (max: 4096 characters)", i);
363			std::process::exit(1);
364		}
365	}
366
367	// Check if we're running with CLI command (first arg is a known command)
368	if args.len() > 1 {
369		match args[1].as_str() {
370			"status" | "restart" | "config" | "metrics" | "logs" | "debug" | "help" | "version" | "-h" | "--help"
371			| "-v" | "--version" => {
372				// Parse CLI command with error handling
373				match CliParser::parse(args.clone()) {
374					Ok(cmd) => {
375						dev_log!("lifecycle", "[Boot] CLI command parsed: {:?}", cmd);
376						return (None, None, Some(cmd));
377					},
378					Err(e) => {
379						eprintln!("[ERROR] Error parsing CLI command: {}", e);
380						eprintln!("[ERROR] Run 'Air help' for usage information");
381						std::process::exit(1);
382					},
383				}
384			},
385			_ => {},
386		}
387	}
388
389	// Parse as daemon arguments with validation
390	let mut config_path:Option<String> = None;
391	let mut bind_address:Option<String> = None;
392
393	let mut i = 0;
394	while i < args.len() {
395		match args[i].as_str() {
396			"--config" | "-c" => {
397				if i + 1 < args.len() {
398					let path = &args[i + 1];
399					// Validate path doesn't contain suspicious characters
400					if path.contains("..") || path.contains('\0') {
401						eprintln!("[ERROR] Invalid config path: contains '..' or null character");
402						std::process::exit(1);
403					}
404					config_path = Some(path.clone());
405					i += 1;
406				} else {
407					eprintln!("[ERROR] --config flag requires a path argument");
408					std::process::exit(1);
409				}
410			},
411			"--bind" | "-b" => {
412				if i + 1 < args.len() {
413					let addr = &args[i + 1];
414					// Basic validation of address format
415					if addr.is_empty() || addr.len() > 256 {
416						eprintln!("[ERROR] Invalid bind address: must be 1-256 characters");
417						std::process::exit(1);
418					}
419					// Full validation happens during bind, but check for null characters
420					if addr.contains('\0') {
421						eprintln!("[ERROR] Invalid bind address: contains null character");
422						std::process::exit(1);
423					}
424					bind_address = Some(addr.clone());
425					i += 1;
426				} else {
427					eprintln!("[ERROR] --bind flag requires an address argument");
428					std::process::exit(1);
429				}
430			},
431			_ => {
432				// Ignore unknown flags or positional arguments
433				// Could add warning for unknown flags if desired
434			},
435		}
436		i += 1;
437	}
438
439	dev_log!(
440		"lifecycle",
441		"[Boot] Daemon mode - config: {:?}, bind: {:?}",
442		config_path,
443		bind_address
444	);
445
446	(config_path, bind_address, None)
447}
448
449/// Handle CLI commands with comprehensive implementation
450///
451/// Executes user commands against the Air daemon. Most commands require
452/// connecting to the running daemon via gRPC. Commands that don't require
453/// a running daemon (like `version`) execute immediately.
454///
455/// # Errors
456///
457/// Returns errors when:
458/// - Daemon connection fails (for commands requiring daemon)
459/// - Command parameters are invalid
460/// - Daemon returns an error response
461/// - I/O operations fail
462///
463/// # FUTURE Enhancements
464/// - Implement actual daemon connection via gRPC
465/// - Add command timeout (default: 30s, configurable)
466/// - Implement graceful degradation for partial failures
467/// - Add retry logic for transient failures
468/// - Add command history/log
469/// - Implement interactive mode
470/// - Add tab-completion support
471async fn HandleCommand(cmd:Command) -> Result<(), Box<dyn std::error::Error>> {
472	// Validate command parameters before execution
473	let validation_result = validate_command(&cmd);
474	if let Err(e) = validation_result {
475		eprintln!("[ERROR] Command validation failed: {}", e);
476		return Err(e.into());
477	}
478
479	match cmd {
480		Command::Help { command } => {
481			// Defensive: Ensure command string is not too long if provided
482			if let Some(ref cmd) = command {
483				if cmd.len() > 128 {
484					eprintln!("[ERROR] Command name too long (max: 128 characters)");
485					return Err("Command name too long".into());
486				}
487			}
488			println!("{}", OutputFormatter::format_help(command.as_deref(), VERSION));
489			Ok(())
490		},
491
492		Command::Version => {
493			println!("Air {} ({})", VERSION, env!("CARGO_PKG_NAME"));
494			println!("Protocol: Version {} (gRPC)", ProtocolVersion);
495			println!("Port: {} (Air), {} (Cocoon)", DefaultBindAddress, "[::1]:50052");
496			println!("Build: {} {}", env!("CARGO_PKG_VERSION"), env!("CARGO_PKG_NAME"));
497			Ok(())
498		},
499
500		Command::Status { service, verbose, json } => {
501			// Validate inputs
502			if let Some(ref svc) = service {
503				if svc.is_empty() || svc.len() > 64 {
504					return Err("Service name must be 1-64 characters".into());
505				}
506			}
507
508			// Connect to daemon via gRPC and request status
509			// For now, perform basic connection check
510
511			// Implementation note: Detailed service status requires gRPC client integration
512			if let Some(svc) = service {
513				println!("📊 Status for service: {}", svc);
514
515				// Attempt connection with timeout
516				match attempt_daemon_connection().await {
517					Ok(_) => {
518						println!("  Status: ⚠️  Running (basic check)");
519						println!("  Note: Connect to gRPC endpoint for detailed status");
520					},
521					Err(e) => {
522						println!("  Status: ❌ Cannot connect to daemon");
523						println!("  Error: {}", e);
524						println!("");
525						println!("  To start the daemon, run: Air --daemon");
526						return Err(format!("Cannot connect to daemon: {}", e).into());
527					},
528				}
529			} else {
530				println!("📊 Air Daemon Status");
531				println!("");
532
533				// Attempt connection
534				match attempt_daemon_connection().await {
535					Ok(_) => {
536						println!("  Overall: ⚠️  Running (basic check)");
537						println!("  Note: Connect to gRPC endpoint for detailed status");
538						println!("");
539						println!("  Services:");
540						println!("    gRPC Server: ✅ Listening");
541						println!("    Authentication: ⚠️  Status check not implemented");
542						println!("    Updates: ⚠️  Status check not implemented");
543						println!("    Download Manager: ⚠️  Status check not implemented");
544						println!("    File Indexer: ⚠️  Status check not implemented");
545					},
546					Err(e) => {
547						println!("  Overall: ❌ Daemon not running");
548						println!("  Error: {}", e);
549						println!("");
550						println!("  To start the daemon, run: Air --daemon");
551						return Err("Daemon not running".into());
552					},
553				}
554			}
555
556			if verbose {
557				println!("");
558				println!("🔍 Verbose Information:");
559				println!("  Debug mode: Disabled by default");
560				println!("  Log level: info");
561				println!("  Config file: {}", DefaultConfigFile);
562				println!("");
563				println!("  Detailed service status can be obtained via gRPC:");
564				println!("    - Service uptime");
565				println!("    - Request/response statistics");
566				println!("    - Error rates and recent errors");
567				println!("    - Resource usage");
568				println!("    - Active connections");
569			}
570
571			if json {
572				println!("");
573				println!("📋 JSON Output:");
574				println!(
575					"{}",
576					serde_json::json!({
577						"overall": "running",
578						"services": {
579							"grpc": "listening",
580							"status": "not_implemented"
581						},
582						"note": "Detailed JSON output not yet implemented"
583					})
584				);
585			}
586
587			Ok(())
588		},
589
590		Command::Restart { service, force } => {
591			// Validate input
592			if let Some(ref svc) = service {
593				if svc.is_empty() || svc.len() > 64 {
594					return Err("Service name must be 1-64 characters".into());
595				}
596			}
597
598			// Restart daemon via gRPC
599			// Implementation note: Requires gRPC client with Restart RPC method
600			println!("🔄 Restart Command");
601			println!("");
602
603			if let Some(svc) = service {
604				println!("Restarting service: {}", svc);
605				println!("  Note: Individual service restart requires gRPC integration");
606				println!("  Workaround: Restart the entire daemon");
607			} else {
608				println!("Restarting all services...");
609				println!("  Note: Full daemon restart requires gRPC integration");
610				println!("  Workaround: Use: kill <pid> && Air --daemon");
611			}
612
613			if force {
614				println!("");
615				println!("⚠️  Force mode enabled");
616				println!(
617					"  Note: Force restart requires proper coordination to gracefully terminate in-progress operations"
618				);
619			}
620
621			Err("Restart command requires gRPC integration".into())
622		},
623
624		Command::Config(config_cmd) => {
625			match config_cmd {
626				ConfigCommand::Get { key } => {
627					// Validate key
628					if key.is_empty() || key.len() > 256 {
629						return Err("Configuration key must be 1-256 characters".into());
630					}
631					if key.contains('\0') || key.contains('\n') {
632						return Err("Configuration key contains invalid characters".into());
633					}
634
635					// Connect to daemon and get config value
636					// Implementation note: Requires gRPC client with GetConfig RPC method
637					println!("⚙️  Get Configuration");
638					println!("  Key: {}", key);
639					println!("");
640
641					match attempt_daemon_connection().await {
642						Ok(_) => {
643							println!("  Status: ✅ Connected to daemon");
644							println!("");
645							println!("  Note: Config retrieval via gRPC not yet implemented");
646							println!("  Config value would be retrieved from daemon's configuration manager");
647						},
648						Err(e) => {
649							println!("  Status: ❌ Cannot connect to daemon");
650							println!("  Error: {}", e);
651							println!("");
652							println!("  Workaround: Check config file directly: cat {}", DefaultConfigFile);
653							return Err(format!("Cannot get config: {}", e).into());
654						},
655					}
656
657					Err("Config 'get' command requires gRPC integration".into())
658				},
659
660				ConfigCommand::Set { key, value } => {
661					// Validate inputs
662					if key.is_empty() || key.len() > 256 {
663						return Err("Configuration key must be 1-256 characters".into());
664					}
665					if value.len() > 8192 {
666						return Err("Configuration value too long (max: 8192 characters)".into());
667					}
668					if key.contains('\0') || key.contains('\n') {
669						return Err("Configuration key contains invalid characters".into());
670					}
671
672					// Connect to daemon and set config value
673					// Implementation note: Requires gRPC client with SetConfig RPC method
674					println!("⚙️  Set Configuration");
675					println!("  Key: {}", key);
676					println!("  Value: {}", value);
677					println!("");
678
679					match attempt_daemon_connection().await {
680						Ok(_) => {
681							println!("  Status: ✅ Connected to daemon");
682							println!("");
683							println!("  Note: Config update via gRPC not yet implemented");
684							println!("  Config value would be set in daemon's configuration manager");
685						},
686						Err(e) => {
687							println!("  Status: ❌ Cannot connect to daemon");
688							println!("  Error: {}", e);
689							println!("");
690							println!("  Workaround: Edit config file directly, then use 'Air config reload'");
691							return Err(format!("Cannot set config: {}", e).into());
692						},
693					}
694
695					println!("");
696					println!("  ⚠️  Warning: Config changes may require reload or restart");
697
698					Err("Config 'set' command requires gRPC integration".into())
699				},
700
701				ConfigCommand::Reload { validate } => {
702					// Reload configuration
703					// Implementation note: Requires gRPC client with ReloadConfig RPC method
704					println!("🔄 Reload Configuration");
705					println!("");
706
707					match attempt_daemon_connection().await {
708						Ok(_) => {
709							println!("  Status: ✅ Connected to daemon");
710							println!("");
711							if validate {
712								println!("  Validating configuration...");
713								println!("  Note: Validation not yet implemented");
714							}
715							println!("  Note: Config reload via gRPC not yet implemented");
716							println!("  Workaround: Restart daemon to apply config changes");
717						},
718						Err(e) => {
719							println!("  Status: ❌ Cannot connect to daemon");
720							println!("  Error: {}", e);
721							return Err(format!("Cannot reload config: {}", e).into());
722						},
723					}
724
725					Err("Config 'reload' command requires gRPC integration".into())
726				},
727
728				ConfigCommand::Show { json } => {
729					// Show configuration
730					// Implementation note: Requires gRPC client with GetFullConfig RPC method
731					println!("⚙️  Show Configuration");
732					println!("");
733
734					if json {
735						println!("  JSON output requested");
736						match attempt_daemon_connection().await {
737							Ok(_) => {
738								println!("  Status: ✅ Connected to daemon");
739								println!("  Note: JSON config export via gRPC not yet implemented");
740							},
741							Err(e) => {
742								println!("  Status: ❌ Cannot connect to daemon");
743								println!("  Error: {}", e);
744								return Err(format!("Cannot show config: {}", e).into());
745							},
746						}
747					} else {
748						println!("  Current Configuration:");
749						match attempt_daemon_connection().await {
750							Ok(_) => {
751								println!("  Status: ✅ Connected to daemon");
752								println!("  Note: Config display via gRPC not yet implemented");
753							},
754							Err(e) => {
755								println!("  Status: ❌ Cannot connect to daemon");
756								println!("  Error: {}", e);
757								println!("  Workaround: View config file: cat {}", DefaultConfigFile);
758								return Err(format!("Cannot show config: {}", e).into());
759							},
760						}
761					}
762
763					println!("");
764					println!("  Default config file: {}", DefaultConfigFile);
765					println!("  Config directory: ~/.config/Air/");
766
767					Err("Config 'show' command requires gRPC integration".into())
768				},
769
770				ConfigCommand::Validate { path } => {
771					// Validate path if provided
772					if let Some(ref p) = path {
773						if p.is_empty() || p.len() > 512 {
774							return Err("Config path must be 1-512 characters".into());
775						}
776						if p.contains("..") || p.contains('\0') {
777							return Err("Config path contains invalid characters".into());
778						}
779					}
780
781					println!("✅ Validate Configuration");
782					println!("");
783
784					let config_path = path.unwrap_or_else(|| DefaultConfigFile.to_string());
785					println!("  Config file: {}", config_path);
786					println!("");
787
788					// Check if file exists
789					match std::path::Path::new(&config_path).exists() {
790						true => {
791							println!("  ✅ Config file exists");
792							println!("  Note: Detailed validation not yet implemented");
793							println!("  Workaround: Use: Air --validate-config");
794						},
795						false => {
796							println!("  ❌ Config file not found");
797							println!("  Hint: Create a config file or use defaults");
798						},
799					}
800
801					Err("Config 'validate' command not yet implemented".into())
802				},
803			}
804		},
805
806		Command::Metrics { json, service } => {
807			// Validate inputs
808			if let Some(ref svc) = service {
809				if svc.is_empty() || svc.len() > 64 {
810					return Err("Service name must be 1-64 characters".into());
811				}
812			}
813
814			println!("📊 Metrics");
815			println!("");
816
817			// Attempt to get metrics from daemon
818			match attempt_daemon_connection().await {
819				Ok(_) => {
820					println!("  Status: ✅ Daemon is running");
821					println!("");
822					println!("  Note: Metrics collection is partially implemented");
823					println!("");
824					println!("  Current Metrics (basic):");
825					println!("    Uptime: Not tracked yet");
826					println!("    Requests: Not tracked yet");
827					println!("    Errors: Not tracked yet");
828					println!("    Memory: Not tracked yet");
829					println!("    CPU: Not tracked yet");
830					println!("");
831					println!("  Note: Comprehensive metrics require gRPC integration:");
832					println!("    - Request/response counters");
833					println!("    - Latency percentiles");
834					println!("    - Error rate tracking");
835					println!("    - Resource usage");
836					println!("    - Connection pool stats");
837					println!("    - Background queue depth");
838				},
839				Err(e) => {
840					println!("  Status: ❌ Cannot connect to daemon");
841					println!("  Error: {}", e);
842					return Err(format!("Cannot retrieve metrics: {}", e).into());
843				},
844			}
845
846			if json {
847				println!("");
848				println!("📋 JSON Output:");
849				println!(
850					"{}",
851					serde_json::json!({
852						"note": "Detailed metrics not yet implemented",
853						"suggestion": "Use /metrics endpoint when daemon is running"
854					})
855				);
856			}
857
858			if let Some(svc) = service {
859				println!("");
860				println!("  Service-specific metrics requested: {}", svc);
861				println!("  Note: Service isolation not yet implemented");
862			}
863
864			Ok(())
865		},
866
867		Command::Logs { service, tail, filter, follow } => {
868			// Validate inputs
869			if let Some(ref svc) = service {
870				if svc.is_empty() || svc.len() > 64 {
871					return Err("Service name must be 1-64 characters".into());
872				}
873			}
874			if let Some(n) = tail {
875				if n < 1 || n > 10000 {
876					return Err("Tail count must be 1-10000 lines".into());
877				}
878			}
879			if let Some(ref f) = filter {
880				if f.is_empty() || f.len() > 512 {
881					return Err("Filter string must be 1-512 characters".into());
882				}
883			}
884
885			println!("📝 Logs");
886			println!("");
887
888			// Check for log file
889			let log_file = std::env::var("AIR_LOG_FILE").ok();
890			let log_dir = std::env::var("AIR_LOG_DIR").ok();
891
892			match (log_file, log_dir) {
893				(Some(file), _) => {
894					println!("  Log file: {}", file);
895
896					// Check if file exists and is readable
897					if std::path::Path::new(&file).exists() {
898						println!("  Status: ✅ Log file exists");
899						println!("");
900
901						// Log tailing and filtering
902						// Implementation note: Requires log file streaming support
903						println!("  Note: Log tailing via file API not yet implemented");
904						println!("  Workaround: Use standard tools:");
905						println!("    - tail -n {} {}", tail.unwrap_or(100), file);
906
907						if let Some(f) = filter {
908							println!("    - grep '{}' {} | tail -n {}", f, file, tail.unwrap_or(100));
909						}
910
911						if follow {
912							println!("    - tail -f {}", file);
913						}
914					} else {
915						println!("  Status: ❌ Log file not found");
916						println!("  Check logging configuration");
917					}
918				},
919				(_, Some(dir)) => {
920					println!("  Log directory: {}", dir);
921					println!("  Note: Log file viewing not yet implemented");
922					println!("  Workaround: Find and view log files in the directory");
923				},
924				_ => {
925					println!("  Log file: Not configured");
926					println!("  Set via: AIR_LOG_FILE=/path/to/Air.log");
927					println!("");
928					println!("  Logs are likely going to stdout/stderr");
929					println!("  Use journalctl (Linux/macOS) or Event Viewer (Windows)");
930				},
931			}
932
933			if let Some(svc) = service {
934				println!("");
935				println!("  Service-specific logs requested: {}", svc);
936				println!("  Note: Service log isolation not yet implemented");
937			}
938
939			// For now, show a placeholder
940			Err("Logs command not yet fully implemented".into())
941		},
942
943		Command::Debug(debug_cmd) => {
944			match debug_cmd {
945				DebugCommand::DumpState { service, json } => {
946					// Validate input
947					if let Some(ref svc) = service {
948						if svc.is_empty() || svc.len() > 64 {
949							return Err("Service name must be 1-64 characters".into());
950						}
951					}
952
953					println!("🔧 Debug: Dump State");
954					println!("");
955
956					if let Some(svc) = service {
957						println!("  Service: {}", svc);
958						println!("  Note: Service state isolation not yet implemented");
959					} else {
960						println!("  Dumping all service states...");
961						println!("  Note: State dumping not yet implemented");
962					}
963
964					if json {
965						println!("");
966						println!("  JSON format requested");
967						println!("  Note: JSON state export not yet implemented");
968					}
969
970					println!("");
971					println!("  Note: State dumping requires gRPC integration:");
972					println!("    - Application state");
973					println!("    - Service states");
974					println!("    - Connection pool");
975					println!("    - Background tasks");
976					println!("    - Metrics cache");
977					println!("    - Configuration snapshot");
978
979					Err("Debug 'dump-state' command not yet implemented".into())
980				},
981
982				DebugCommand::DumpConnections { format } => {
983					println!("🔧 Debug: Dump Connections");
984					println!("");
985
986					match attempt_daemon_connection().await {
987						Ok(_) => {
988							println!("  Status: ✅ Daemon is running");
989							println!("");
990							println!("  Active Connections: 0");
991							println!("  Note: Connection tracking not yet implemented");
992						},
993						Err(e) => {
994							println!("  Status: ❌ Cannot connect to daemon");
995							println!("  Error: {}", e);
996							return Err(format!("Cannot dump connections: {}", e).into());
997						},
998					}
999
1000					if let Some(fmt) = format {
1001						println!("");
1002						println!("  Format: {}", fmt);
1003						println!("  Note: Custom format not yet implemented");
1004					}
1005
1006					println!("");
1007					println!("  Note: Connection dump requires gRPC integration:");
1008					println!("    - Connection ID");
1009					println!("    - Remote address");
1010					println!("    - Connected at timestamp");
1011					println!("    - Last activity");
1012					println!("    - Active requests");
1013					println!("    - Bytes transferred");
1014
1015					Err("Debug 'dump-connections' command not yet implemented".into())
1016				},
1017
1018				DebugCommand::HealthCheck { verbose, service } => {
1019					// Validate input
1020					if let Some(ref svc) = service {
1021						if svc.is_empty() || svc.len() > 64 {
1022							return Err("Service name must be 1-64 characters".into());
1023						}
1024					}
1025
1026					println!("🔧 Debug: Health Check");
1027					println!("");
1028
1029					match attempt_daemon_connection().await {
1030						Ok(_) => {
1031							println!("  Overall: ⚠️  Basic check passed");
1032							println!("");
1033
1034							if let Some(svc) = service {
1035								println!("  Service: {}", svc);
1036								println!("  Status: Not checked (detailed checks not implemented)");
1037							} else {
1038								println!("  Services:");
1039								println!("    gRPC Server: ✅ Responding");
1040								println!("    Authentication: ⏸️  Not checked");
1041								println!("    Updates: ⏸️  Not checked");
1042								println!("    Download Manager: ⏸️  Not checked");
1043								println!("    File Indexer: ⏸️  Not checked");
1044							}
1045
1046							if verbose {
1047								println!("");
1048								println!("  🔍 Verbose Information:");
1049								println!("    Last health check: Not tracked");
1050								println!("    Health check interval: 30s (default)");
1051								println!("    Failure threshold: 3 (configurable)");
1052								println!("    Recovery threshold: 2 (configurable)");
1053							}
1054						},
1055						Err(e) => {
1056							println!("  Overall: ❌ Daemon unreachable");
1057							println!("  Error: {}", e);
1058							return Err(format!("Health check failed: {}", e).into());
1059						},
1060					}
1061
1062					Err("Debug 'health-check' not detailed yet".into())
1063				},
1064
1065				DebugCommand::Diagnostics { level } => {
1066					println!("🔧 Debug: Diagnostics");
1067					println!("");
1068					println!("  Level: {:?}", level);
1069					println!("");
1070
1071					// Show system information
1072					println!("  System Information:");
1073					println!("    OS: {}", std::env::consts::OS);
1074					println!("    Arch: {}", std::env::consts::ARCH);
1075					println!("    Air Version: {}", VERSION);
1076					println!("");
1077
1078					match attempt_daemon_connection().await {
1079						Ok(_) => {
1080							println!("  Daemon: ✅ Running");
1081						},
1082						Err(e) => {
1083							println!("  Daemon: ❌ Running");
1084							println!("  Error: {}", e);
1085						},
1086					}
1087
1088					println!("");
1089					println!("  Note: Advanced diagnostics require additional infrastructure:");
1090					println!("    - Thread dump");
1091					println!("    - Memory profiling");
1092					println!("    - Lock contention analysis");
1093					println!("    - Resource leak detection");
1094					println!("    - Performance bottlenecks");
1095
1096					Ok(())
1097				},
1098			}
1099		},
1100	}
1101}
1102
1103/// Validate command parameters to prevent invalid inputs
1104///
1105/// # FUTURE Enhancements
1106/// - Add timeout parameter validation
1107/// - Add rate limit checks for commands
1108/// - Implement command permission checks
1109fn validate_command(cmd:&Command) -> Result<(), String> {
1110	match cmd {
1111		Command::Help { command } => {
1112			if let Some(cmd) = command {
1113				if cmd.len() > 128 {
1114					return Err("Command name too long (max: 128)".to_string());
1115				}
1116			}
1117		},
1118		_ => {},
1119	}
1120	Ok(())
1121}
1122
1123/// Attempt to connect to the running daemon
1124///
1125/// Creates a basic TCP connection to check if the daemon is running.
1126/// This is a simplified check for pre-implementation status.
1127///
1128/// # FUTURE Enhancements
1129/// - Implement proper gRPC client connection
1130/// - Add connection timeout configuration
1131/// - Implement connection pooling
1132/// - Add authentication
1133/// Attempt to connect to the running daemon with retry logic
1134///
1135/// Creates a basic TCP connection to check if the daemon is running.
1136/// Implements exponential backoff retry for resilience.
1137///
1138/// # Arguments
1139/// * `max_retries` - Maximum number of retry attempts (default: 3)
1140/// * `initial_delay_ms` - Initial delay in milliseconds before first retry
1141///   (default: 500)
1142///
1143/// # Returns
1144/// Result<(), String> - Ok if connection successful, Err with message if failed
1145async fn attempt_daemon_connection_with_retry(max_retries:usize, initial_delay_ms:u64) -> Result<(), String> {
1146	use tokio::{
1147		net::TcpStream,
1148		time::{Duration, timeout},
1149	};
1150
1151	let addr = DefaultBindAddress;
1152	let mut attempt = 0;
1153	let mut delay_ms = initial_delay_ms;
1154
1155	loop {
1156		attempt += 1;
1157		dev_log!("lifecycle", "[DaemonConnection] Attempt {} of {}", attempt, max_retries + 1);
1158
1159		// Timeout: 5 seconds per attempt
1160		let connection_result = timeout(Duration::from_secs(5), async { TcpStream::connect(addr).await }).await;
1161
1162		match connection_result {
1163			Ok(Ok(_stream)) => {
1164				dev_log!("lifecycle", "[DaemonConnection] Connected successfully on attempt {}", attempt);
1165				return Ok(());
1166			},
1167			Ok(Err(e)) => {
1168				dev_log!("lifecycle", "[DaemonConnection] Attempt {} failed: {}", attempt, e);
1169			},
1170			Err(_) => {
1171				dev_log!("lifecycle", "[DaemonConnection] Attempt {} timed out", attempt);
1172			},
1173		}
1174
1175		// Check if we've exhausted retries
1176		if attempt > max_retries {
1177			break;
1178		}
1179
1180		// Exponential backoff: wait before next retry
1181		dev_log!("lifecycle", "[DaemonConnection] Waiting {}ms before retry...", delay_ms);
1182		tokio::time::sleep(Duration::from_millis(delay_ms)).await;
1183		delay_ms = delay_ms * 2; // Double the delay for next attempt
1184	}
1185
1186	Err(format!("Failed to connect after {} attempts", max_retries + 1))
1187}
1188
1189/// Attempt to connect to the running daemon (simple version with default retry)
1190///
1191/// This is the main entry point that uses default retry settings.
1192/// For more control, use attempt_daemon_connection_with_retry directly.
1193async fn attempt_daemon_connection() -> Result<(), String> {
1194	// Default: 3 retries with 500ms initial delay
1195	attempt_daemon_connection_with_retry(3, 500).await
1196}
1197
1198/// Handler for /metrics endpoint - returns Prometheus format metrics
1199///
1200/// Exports all collected metrics in Prometheus text format for scraping
1201/// by monitoring systems like Prometheus, Grafana, or custom dashboards.
1202///
1203/// Metrics include:
1204/// - Request counters (total, successful, failed)
1205/// - Response times (histogram)
1206/// - Resource usage (memory, CPU)
1207/// - Connection counts
1208/// - Background task status
1209///
1210/// # FUTURE Enhancements
1211/// - Add timeout for metrics export (should not block daemon)
1212/// - Implement metric label support (service, host, etc.)
1213/// - Add counter reset capability
1214/// - Implement metric filtering via query parameters
1215/// - Add histogram quantiles (p50, p95, p99)
1216/// - Support both Prometheus and OpenMetrics formats
1217#[allow(dead_code)]
1218fn HandleMetricsRequest() -> String {
1219	// Defensive: Use a timeout to prevent metrics export from blocking
1220	let _timeout_duration = std::time::Duration::from_millis(100);
1221
1222	let metrics_collector = Metrics::GetMetrics();
1223
1224	// Export metrics with error handling and timeout
1225	let export_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| metrics_collector.ExportMetrics()));
1226
1227	match export_result {
1228		Ok(Ok(metrics_text)) => {
1229			// Validate metrics text is not too large
1230			if metrics_text.len() > 10_000_000 {
1231				dev_log!(
1232					"metrics",
1233					"error: [Metrics] Exported metrics unreasonably large (size: {} bytes)",
1234					metrics_text.len()
1235				);
1236				format!("# ERROR: Metrics export too large (max: 10MB)\n")
1237			} else {
1238				metrics_text
1239			}
1240		},
1241		Ok(Err(e)) => {
1242			dev_log!("metrics", "error: [Metrics] Failed to export metrics: {}", e);
1243			format!("# ERROR: Failed to export metrics: {}\n", e)
1244		},
1245		Err(_) => {
1246			dev_log!("metrics", "error: [Metrics] Metrics export panicked");
1247			format!("# ERROR: Metrics export failed due to internal error\n")
1248		},
1249	}
1250}
1251
1252// =============================================================================
1253// Main Application Entry Point
1254// =============================================================================
1255
1256/// The main asynchronous function that sets up and runs the Air daemon
1257///
1258/// This is the primary entry point for the Air background service. It
1259/// coordinates all initialization, starts the gRPC server, manages the daemon
1260/// lifecycle, and handles graceful shutdown.
1261///
1262/// # Startup Sequence
1263///
1264/// 1. Initialize logging and observability (metrics, tracing)
1265/// 2. Parse command-line arguments (for CLI commands or daemon config)
1266/// 3. Load configuration (with validation)
1267/// 4. Acquire daemon lock (ensure single instance)
1268/// 5. Initialize application state
1269/// 6. Create and register core services
1270/// 7. Start gRPC server (Vine protocol)
1271/// 8. Start background tasks and monitoring
1272/// 9. Wait for shutdown signal
1273/// 10. Graceful shutdown sequence
1274///
1275/// # Defensive Coding
1276///
1277/// All operations include:
1278/// - Input validation and sanitization
1279/// - Timeout handling for async operations
1280/// - Error recovery and logging
1281/// - Resource cleanup on errors
1282/// - Panic handling in critical sections
1283///
1284/// # FUTURE Enhancements
1285/// - Implement configuration hot-reload signal handling (SIGHUP)
1286/// - Add startup timeout and failure recovery
1287/// - Implement daemon mode forking (Unix)
1288/// - Add Windows service integration
1289/// - Implement crash recovery and restart
1290/// - Add pre-flight environment checks
1291/// - Implement feature flag system
1292async fn Main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1293	// -------------------------------------------------------------------------
1294	// [Boot] [Telemetry] Bring up shared dual-pipe (PostHog + OTLP) so any
1295	// boot error captured from this point lands in the project. No-op in
1296	// release builds and when `Capture=false`. Idempotent.
1297	// -------------------------------------------------------------------------
1298	CommonLibrary::Telemetry::Initialize::Fn(CommonLibrary::Telemetry::Tier::Tier::Air).await;
1299
1300	// -------------------------------------------------------------------------
1301	// [Boot] [Logging] Initialize logging system
1302	// -------------------------------------------------------------------------
1303	InitializeLogging();
1304
1305	dev_log!("lifecycle", "[Boot] ===========================================");
1306	dev_log!("lifecycle", "[Boot] Starting Air Daemon");
1307	dev_log!("lifecycle", "[Boot] ===========================================");
1308	dev_log!(
1309		"lifecycle",
1310		"[Boot] Version: {} ({})",
1311		env!("CARGO_PKG_VERSION"),
1312		env!("CARGO_PKG_NAME")
1313	);
1314	let build_timestamp = env::var("BUILD_TIMESTAMP").unwrap_or_else(|_| "unknown".to_string());
1315	dev_log!("lifecycle", "[Boot] Build: {}", build_timestamp);
1316	dev_log!(
1317		"lifecycle",
1318		"[Boot] Target: {}-{}",
1319		std::env::consts::OS,
1320		std::env::consts::ARCH
1321	);
1322
1323	// -------------------------------------------------------------------------
1324	// [Boot] [Environment] Validate environment before starting
1325	// -------------------------------------------------------------------------
1326	dev_log!("lifecycle", "[Boot] Validating environment...");
1327
1328	if let Err(e) = validate_environment().await {
1329		dev_log!("lifecycle", "error: [Boot] Environment validation failed: {}", e);
1330		return Err(format!("Environment validation failed: {}", e).into());
1331	}
1332
1333	dev_log!("lifecycle", "[Boot] Environment validation passed");
1334
1335	// -------------------------------------------------------------------------
1336	// [Boot] [Observability] Initialize metrics and tracing
1337	// -------------------------------------------------------------------------
1338	Trace!("[Boot] [Observability] Initializing observability systems...");
1339
1340	// Initialize metrics with error handling
1341	if let Err(e) = Metrics::InitializeMetrics() {
1342		dev_log!("lifecycle", "error: [Boot] Failed to initialize metrics: {}", e);
1343		// Non-fatal: continue without metrics
1344	} else {
1345		dev_log!("lifecycle", "[Boot] [Observability] Metrics system initialized");
1346	}
1347
1348	// Initialize tracing with error handling
1349	if let Err(e) = Tracing::initialize_tracing(None) {
1350		dev_log!("lifecycle", "error: [Boot] Failed to initialize tracing: {}", e);
1351		// Non-fatal: continue without tracing
1352	} else {
1353		dev_log!("lifecycle", "[Boot] [Observability] Tracing system initialized");
1354	}
1355
1356	dev_log!("lifecycle", "[Boot] [Observability] Observability systems initialized");
1357
1358	// -------------------------------------------------------------------------
1359	// [Boot] [Args] Parse command line arguments
1360	// -------------------------------------------------------------------------
1361	Trace!("[Boot] [Args] Parsing command line arguments...");
1362
1363	let (config_path, bind_address, cli_command) = ParseArguments();
1364
1365	// If a CLI command was provided, handle it and exit
1366	if let Some(cmd) = cli_command {
1367		dev_log!("lifecycle", "[Boot] CLI command detected, executing...");
1368		let result = HandleCommand(cmd).await;
1369
1370		match &result {
1371			Ok(_) => {
1372				dev_log!("lifecycle", "[Boot] CLI command completed successfully");
1373				std::process::exit(0);
1374			},
1375			Err(e) => {
1376				dev_log!("lifecycle", "error: [Boot] CLI command failed: {}", e);
1377				std::process::exit(1);
1378			},
1379		}
1380	}
1381
1382	// -------------------------------------------------------------------------
1383	// [Boot] [Configuration] Load configuration
1384	// -------------------------------------------------------------------------
1385	Trace!("[Boot] [Configuration] Loading configuration...");
1386
1387	let config_manager = match ConfigurationManager::New(config_path) {
1388		Ok(cm) => cm,
1389		Err(e) => {
1390			dev_log!("lifecycle", "error: [Boot] Failed to create configuration manager: {}", e);
1391			return Err(format!("Configuration manager initialization failed: {}", e).into());
1392		},
1393	};
1394
1395	// Load configuration with timeout
1396	let configuration:std::sync::Arc<AirLibrary::Configuration::AirConfiguration> =
1397		match tokio::time::timeout(Duration::from_secs(10), config_manager.LoadConfiguration()).await {
1398			Ok(Ok(config)) => {
1399				dev_log!("lifecycle", "[Boot] [Configuration] Configuration loaded successfully");
1400				std::sync::Arc::new(config)
1401			},
1402			Ok(Err(e)) => {
1403				dev_log!("lifecycle", "error: [Boot] Failed to load configuration: {}", e);
1404				return Err(format!("Configuration load failed: {}", e).into());
1405			},
1406			Err(_) => {
1407				dev_log!("lifecycle", "error: [Boot] Configuration load timed out");
1408				return Err("Configuration load timed out".into());
1409			},
1410		};
1411
1412	// Validate critical configuration values
1413	validate_configuration(&configuration)?;
1414
1415	// -------------------------------------------------------------------------
1416	// [Boot] [Daemon] Initialize daemon lifecycle management
1417	// -------------------------------------------------------------------------
1418	Trace!("[Boot] [Daemon] Initializing daemon lifecycle management...");
1419
1420	let daemon_manager = match DaemonManager::New(None) {
1421		Ok(dm) => dm,
1422		Err(e) => {
1423			dev_log!("lifecycle", "error: [Boot] Failed to create daemon manager: {}", e);
1424			return Err(format!("Daemon manager initialization failed: {}", e).into());
1425		},
1426	};
1427
1428	// Acquire daemon lock to ensure single instance with timeout
1429	match tokio::time::timeout(Duration::from_secs(5), daemon_manager.AcquireLock()).await {
1430		Ok(Ok(_)) => {
1431			dev_log!("lifecycle", "[Boot] [Daemon] Daemon lock acquired successfully");
1432		},
1433		Ok(Err(e)) => {
1434			dev_log!("lifecycle", "error: [Boot] Failed to acquire daemon lock: {}", e);
1435			dev_log!("lifecycle", "error: [Boot] Another instance may already be running");
1436			return Err(format!("Daemon lock acquisition failed: {}", e).into());
1437		},
1438		Err(_) => {
1439			dev_log!("lifecycle", "error: [Boot] Daemon lock acquisition timed out");
1440			return Err("Daemon lock acquisition timed out".into());
1441		},
1442	}
1443
1444	// -------------------------------------------------------------------------
1445	// [Boot] [Health] Initialize health check system
1446	// -------------------------------------------------------------------------
1447	Trace!("[Boot] [Health] Initializing health check system...");
1448
1449	let health_manager:std::sync::Arc<HealthCheckManager> = Arc::new(HealthCheckManager::new(None));
1450
1451	dev_log!("lifecycle", "[Boot] [Health] Health check system initialized");
1452
1453	// -------------------------------------------------------------------------
1454	// [Boot] [State] Initialize application state
1455	// -------------------------------------------------------------------------
1456	Trace!("[Boot] [State] Initializing application state...");
1457
1458	let AppState:std::sync::Arc<ApplicationState> =
1459		match tokio::time::timeout(Duration::from_secs(10), ApplicationState::New(configuration.clone())).await {
1460			Ok(Ok(state)) => {
1461				dev_log!("lifecycle", "[Boot] [State] Application state initialized");
1462				Arc::new(state)
1463			},
1464			Ok(Err(e)) => {
1465				dev_log!("lifecycle", "error: [Boot] Failed to initialize application state: {}", e);
1466				// Attempt to release lock before returning
1467				let _ = daemon_manager.ReleaseLock().await;
1468				return Err(format!("Application state initialization failed: {}", e).into());
1469			},
1470			Err(_) => {
1471				dev_log!("lifecycle", "error: [Boot] Application state initialization timed out");
1472				let _ = daemon_manager.ReleaseLock().await;
1473				return Err("Application state initialization timed out".into());
1474			},
1475		};
1476
1477	// -------------------------------------------------------------------------
1478	// [Boot] [Services] Initialize core services
1479	// -------------------------------------------------------------------------
1480	Trace!("[Boot] [Services] Initializing core services...");
1481
1482	// Initialize each service with error handling
1483	let auth_service:std::sync::Arc<AuthenticationService> =
1484		match tokio::time::timeout(Duration::from_secs(10), AuthenticationService::new(AppState.clone())).await {
1485			Ok(Ok(svc)) => Arc::new(svc),
1486			Ok(Err(e)) => {
1487				dev_log!("lifecycle", "error: [Boot] Failed to initialize authentication service: {}", e);
1488				return Err(format!("Authentication service initialization failed: {}", e).into());
1489			},
1490			Err(_) => {
1491				dev_log!("lifecycle", "error: [Boot] Authentication service initialization timed out");
1492				return Err("Authentication service initialization timed out".into());
1493			},
1494		};
1495
1496	let update_manager:std::sync::Arc<UpdateManager> =
1497		match tokio::time::timeout(Duration::from_secs(10), UpdateManager::new(AppState.clone())).await {
1498			Ok(Ok(svc)) => Arc::new(svc),
1499			Ok(Err(e)) => {
1500				dev_log!("lifecycle", "error: [Boot] Failed to initialize update manager: {}", e);
1501				return Err(format!("Update manager initialization failed: {}", e).into());
1502			},
1503			Err(_) => {
1504				dev_log!("lifecycle", "error: [Boot] Update manager initialization timed out");
1505				return Err("Update manager initialization timed out".into());
1506			},
1507		};
1508
1509	let download_manager:std::sync::Arc<DownloadManager> =
1510		match tokio::time::timeout(Duration::from_secs(10), DownloadManager::new(AppState.clone())).await {
1511			Ok(Ok(svc)) => Arc::new(svc),
1512			Ok(Err(e)) => {
1513				dev_log!("lifecycle", "error: [Boot] Failed to initialize download manager: {}", e);
1514				return Err(format!("Download manager initialization failed: {}", e).into());
1515			},
1516			Err(_) => {
1517				dev_log!("lifecycle", "error: [Boot] Download manager initialization timed out");
1518				return Err("Download manager initialization timed out".into());
1519			},
1520		};
1521
1522	let file_indexer:std::sync::Arc<FileIndexer> =
1523		match tokio::time::timeout(Duration::from_secs(10), FileIndexer::new(AppState.clone())).await {
1524			Ok(Ok(svc)) => Arc::new(svc),
1525			Ok(Err(e)) => {
1526				dev_log!("lifecycle", "error: [Boot] Failed to initialize file indexer: {}", e);
1527				return Err(format!("File indexer initialization failed: {}", e).into());
1528			},
1529			Err(_) => {
1530				dev_log!("lifecycle", "error: [Boot] File indexer initialization timed out");
1531				return Err("File indexer initialization timed out".into());
1532			},
1533		};
1534
1535	dev_log!("lifecycle", "[Boot] [Services] All core services initialized successfully");
1536
1537	// -------------------------------------------------------------------------
1538	// [Boot] [Health] Register services for health monitoring
1539	// -------------------------------------------------------------------------
1540	Trace!("[Boot] [Health] Registering services for health monitoring...");
1541
1542	// Register each service with validation
1543	let service_registrations = vec![
1544		("authentication", HealthCheckLevel::Functional),
1545		("updates", HealthCheckLevel::Functional),
1546		("downloader", HealthCheckLevel::Functional),
1547		("indexing", HealthCheckLevel::Functional),
1548		("grpc", HealthCheckLevel::Responsive),
1549		("connections", HealthCheckLevel::Alive),
1550	];
1551
1552	for (service_name, level) in service_registrations {
1553		match tokio::time::timeout(
1554			Duration::from_secs(5),
1555			health_manager.RegisterService(service_name.to_string(), level),
1556		)
1557		.await
1558		{
1559			Ok(result) => {
1560				match result {
1561					Ok(_) => {
1562						dev_log!("lifecycle", "[Boot] [Health] Registered service: {}", service_name);
1563					},
1564					Err(e) => {
1565						dev_log!("lifecycle", "warn: [Boot] Failed to register service {}: {}", service_name, e);
1566						// Non-fatal: continue without this service's health
1567						// checks
1568					},
1569				}
1570			},
1571			Err(_) => {
1572				dev_log!("lifecycle", "warn: [Boot] Service registration timed out: {}", service_name);
1573			},
1574		}
1575	}
1576
1577	dev_log!("lifecycle", "[Boot] [Health] Service health monitoring configured");
1578
1579	// -------------------------------------------------------------------------
1580	// [Boot] [Vine] Initialize gRPC server
1581	// -------------------------------------------------------------------------
1582	Trace!("[Boot] [Vine] Initializing gRPC server...");
1583
1584	// Parse bind address with validation
1585	let bind_addr:SocketAddr = match bind_address {
1586		Some(addr) => {
1587			match addr.parse() {
1588				Ok(parsed) => {
1589					dev_log!("lifecycle", "[Boot] [Vine] Using custom bind address: {}", parsed);
1590					parsed
1591				},
1592				Err(e) => {
1593					dev_log!("lifecycle", "error: [Boot] Invalid bind address '{}': {}", addr, e);
1594					return Err(format!("Invalid bind address: {}", e).into());
1595				},
1596			}
1597		},
1598		None => {
1599			match DefaultBindAddress.parse() {
1600				Ok(parsed) => parsed,
1601				Err(e) => {
1602					dev_log!(
1603						"lifecycle",
1604						"error: [Boot] Invalid default bind address '{}': {}",
1605						DefaultBindAddress,
1606						e
1607					);
1608					return Err(format!("Invalid default bind address: {}", e).into());
1609				},
1610			}
1611		},
1612	};
1613
1614	dev_log!("lifecycle", "[Boot] [Vine] Configuring gRPC server on {}", bind_addr);
1615
1616	// Create gRPC service implementation with all dependencies
1617	let vine_service = AirVinegRPCService::new(
1618		AppState.clone(),
1619		auth_service.clone(),
1620		update_manager.clone(),
1621		download_manager.clone(),
1622		file_indexer.clone(),
1623	);
1624
1625	// Create a oneshot channel to signal server shutdown
1626	let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
1627
1628	// Spawn the tonic gRPC server with panic handling
1629	let server_handle:tokio::task::JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> =
1630		tokio::spawn(async move {
1631			dev_log!("lifecycle", "[Vine] Starting gRPC server on {}", bind_addr);
1632
1633			let svc = AirServiceServer::new(vine_service);
1634
1635			let server = tonic::transport::Server::builder()
1636				.add_service(svc)
1637				.serve_with_shutdown(bind_addr, async {
1638					// Wait for shutdown signal from main
1639					let _ = shutdown_rx.await;
1640					dev_log!("lifecycle", "[Vine] Shutdown signal received, stopping server...");
1641				});
1642
1643			dev_log!("lifecycle", "[Vine] gRPC server listening on {}", bind_addr);
1644
1645			match server.await {
1646				Ok(_) => {
1647					dev_log!("lifecycle", "[Vine] gRPC server stopped cleanly");
1648					Ok(())
1649				},
1650				Err(e) => {
1651					dev_log!("grpc", "error: [Vine] gRPC server error: {}", e);
1652					Err(e.into())
1653				},
1654			}
1655		});
1656
1657	// Wait a bit for the server to start
1658	tokio::time::sleep(Duration::from_millis(100)).await;
1659
1660	// Check if server task panicked or failed early
1661	if server_handle.is_finished() {
1662		dev_log!("lifecycle", "error: [Boot] gRPC server failed to start");
1663		let _ = daemon_manager.ReleaseLock().await;
1664		return Err("gRPC server failed to start".into());
1665	}
1666
1667	// -------------------------------------------------------------------------
1668	// [Boot] [Monitoring] Start background monitoring tasks
1669	// -------------------------------------------------------------------------
1670	Trace!("[Boot] [Monitoring] Starting background monitoring tasks...");
1671
1672	// Start connection monitoring background task
1673	let connection_monitor_handle:tokio::task::JoinHandle<()> = tokio::spawn({
1674		let AppState = AppState.clone();
1675		let health_manager = health_manager.clone();
1676		async move {
1677			let mut interval = interval(Duration::from_secs(60)); // Check every minute
1678			loop {
1679				interval.tick().await;
1680
1681				// Update resource usage with error handling
1682				if let Err(e) = AppState.UpdateResourceUsage().await {
1683					dev_log!("lifecycle", "warn: [ConnectionMonitor] Failed to update resource usage: {}", e);
1684				}
1685
1686				// Get resource metrics
1687				let resources = AppState.GetResourceUsage().await;
1688
1689				// Record metrics
1690				let metrics_collector = Metrics::GetMetrics();
1691				metrics_collector.UpdateResourceMetrics(
1692					(resources.MemoryUsageMb * 1024.0 * 1024.0) as u64, // Convert MB to bytes
1693					resources.CPUUsagePercent,
1694					AppState.GetActiveConnectionCount().await as u64,
1695					0, // Thread count: Requires tokio runtime metrics integration
1696				);
1697
1698				// Clean up stale connections (5 minute timeout)
1699				if let Err(e) = AppState.CleanupStaleConnections(300).await {
1700					dev_log!(
1701						"lifecycle",
1702						"warn: [ConnectionMonitor] Failed to cleanup stale connections: {}",
1703						e
1704					);
1705				}
1706
1707				// Perform health checks
1708				match health_manager.CheckService("connections").await {
1709					Ok(_) => {},
1710					Err(e) => {
1711						dev_log!("lifecycle", "warn: [ConnectionMonitor] Health check failed: {}", e);
1712
1713						// Record metrics for failed health check
1714						let metrics_collector = Metrics::GetMetrics();
1715						metrics_collector.RecordRequestFailure("health_check_failed", 0.0);
1716					},
1717				}
1718
1719				dev_log!(
1720					"lifecycle",
1721					"[ConnectionMonitor] Active connections: {}",
1722					AppState.GetActiveConnectionCount().await
1723				);
1724			}
1725		}
1726	});
1727
1728	// Register background task with error handling
1729	if let Err(e) = AppState.RegisterBackgroundTask(connection_monitor_handle).await {
1730		dev_log!("lifecycle", "warn: [Boot] Failed to register connection monitor: {}", e);
1731		// Non-fatal: continue monitoring may not be tracked
1732	}
1733
1734	// Start health monitoring background task
1735	let health_monitor_handle:tokio::task::JoinHandle<()> = tokio::spawn({
1736		let health_manager = health_manager.clone();
1737		async move {
1738			let mut interval = interval(Duration::from_secs(30)); // Check every 30 seconds
1739			loop {
1740				interval.tick().await;
1741
1742				// Perform comprehensive health checks
1743				let services = ["authentication", "updates", "downloader", "indexing", "grpc"];
1744				for service in services.iter() {
1745					if let Err(e) = health_manager.CheckService(service).await {
1746						dev_log!("lifecycle", "warn: [HealthMonitor] Health check failed for {}: {}", service, e);
1747					}
1748				}
1749
1750				// Log overall health status
1751				let overall_health = health_manager.GetOverallHealth().await;
1752				dev_log!("lifecycle", "[HealthMonitor] Overall health: {:?}", overall_health);
1753			}
1754		}
1755	});
1756
1757	// Register health monitoring task with error handling
1758	if let Err(e) = AppState.RegisterBackgroundTask(health_monitor_handle).await {
1759		dev_log!("lifecycle", "warn: [Boot] Failed to register health monitor: {}", e);
1760		// Non-fatal: continue monitoring may not be tracked
1761	}
1762
1763	// -------------------------------------------------------------------------
1764	// [Boot] [Startup] Start services
1765	// -------------------------------------------------------------------------
1766	Trace!("[Boot] [Startup] Starting background services...");
1767
1768	// Start background tasks for services that support it
1769	let _ = auth_service.StartBackgroundTasks().await?;
1770	let _ = update_manager.StartBackgroundTasks().await?;
1771	let _ = download_manager.StartBackgroundTasks().await?;
1772	// FileIndexer does not have background tasks, it's used directly
1773	let _indexing_handle = None::<tokio::task::JoinHandle<()>>;
1774
1775	dev_log!("lifecycle", "[Boot] [Startup] All services started successfully");
1776
1777	// -------------------------------------------------------------------------
1778	// [Runtime] Run server and wait for shutdown
1779	// -------------------------------------------------------------------------
1780	dev_log!("lifecycle", "===========================================");
1781	dev_log!("lifecycle", "[Runtime] Air Daemon is now running");
1782	dev_log!("lifecycle", "[Runtime] Listening on {} for Mountain connections", bind_addr);
1783	dev_log!("lifecycle", "[Runtime] Protocol Version: {}", ProtocolVersion);
1784	dev_log!("lifecycle", "[Runtime] Cocoon Port: 50052");
1785	dev_log!("lifecycle", "===========================================");
1786	dev_log!("lifecycle", "");
1787	dev_log!("lifecycle", "Running. Press Ctrl+C to stop.");
1788	dev_log!("lifecycle", "");
1789
1790	// Wait for shutdown signal
1791	WaitForShutdownSignal().await;
1792
1793	// Signal gRPC server to shut down
1794	dev_log!("lifecycle", "[Shutdown] Signaling gRPC server to stop...");
1795	let _ = shutdown_tx.send(());
1796
1797	// Await the server task to finish with timeout
1798	match tokio::time::timeout(Duration::from_secs(30), server_handle).await {
1799		Ok(Ok(Ok(_))) => {
1800			dev_log!("lifecycle", "[Shutdown] gRPC server stopped normally");
1801		},
1802		Ok(Ok(Err(e))) => {
1803			dev_log!("lifecycle", "warn: [Shutdown] gRPC server stopped with error: {}", e);
1804		},
1805		Ok(Err(e)) => {
1806			dev_log!("lifecycle", "warn: [Shutdown] gRPC server task panicked: {:?}", e);
1807		},
1808		Err(_) => {
1809			dev_log!("lifecycle", "warn: [Shutdown] gRPC server shutdown timed out");
1810		},
1811	}
1812
1813	// -------------------------------------------------------------------------
1814	// [Shutdown] Graceful shutdown
1815	// -------------------------------------------------------------------------
1816	dev_log!("lifecycle", "===========================================");
1817	dev_log!("lifecycle", "[Shutdown] Initiating graceful shutdown...");
1818	dev_log!("lifecycle", "===========================================");
1819
1820	// Stop all background tasks with timeout
1821	dev_log!("lifecycle", "[Shutdown] Stopping background tasks...");
1822	if let Err(_) =
1823		tokio::time::timeout(Duration::from_secs(10), async { AppState.StopAllBackgroundTasks().await }).await
1824	{
1825		dev_log!("lifecycle", "warn: [Shutdown] Background tasks stop timed out or failed");
1826	}
1827
1828	// Stop background services
1829	dev_log!("lifecycle", "[Shutdown] Stopping background services...");
1830	auth_service.StopBackgroundTasks().await;
1831	update_manager.StopBackgroundTasks().await;
1832	download_manager.StopBackgroundTasks().await;
1833
1834	// Log final statistics
1835	dev_log!("lifecycle", "[Shutdown] Collecting final statistics...");
1836
1837	let metrics = AppState.GetMetrics().await;
1838	let resources = AppState.GetResourceUsage().await;
1839	let health_stats:HealthStatistics = health_manager.GetHealthStatistics().await;
1840
1841	// Get final metrics data
1842	let metrics_data = Metrics::GetMetrics().GetMetricsData();
1843
1844	dev_log!("lifecycle", "===========================================");
1845	dev_log!("lifecycle", "[Shutdown] Final Statistics");
1846	dev_log!("lifecycle", "===========================================");
1847	dev_log!("lifecycle", "[Shutdown] Requests:");
1848	dev_log!("lifecycle", " - Successful: {}", metrics.SuccessfulRequest);
1849	dev_log!("lifecycle", " - Failed: {}", metrics.FailedRequest);
1850	dev_log!("lifecycle", "[Shutdown] Metrics:");
1851	dev_log!("lifecycle", "  - Success rate: {:.2}%", metrics_data.SuccessRate());
1852	dev_log!("lifecycle", "  - Error rate: {:.2}%", metrics_data.ErrorRate());
1853	dev_log!("lifecycle", "[Shutdown] Resources:");
1854	dev_log!("lifecycle", "  - Memory: {:.2} MB", resources.MemoryUsageMb);
1855	dev_log!("lifecycle", "  - CPU: {:.2}%", resources.CPUUsagePercent);
1856	dev_log!("lifecycle", "[Shutdown] Health:");
1857	dev_log!("lifecycle", "  - Overall: {:.2}%", health_stats.OverallHealthPercentage());
1858	dev_log!(
1859		"lifecycle",
1860		"  - Healthy services: {}/{}",
1861		health_stats.HealthyServices,
1862		health_stats.TotalServices
1863	);
1864	dev_log!("lifecycle", "===========================================");
1865
1866	// Release daemon lock
1867	dev_log!("lifecycle", "[Shutdown] Releasing daemon lock...");
1868	if let Err(e) = daemon_manager.ReleaseLock().await {
1869		dev_log!("lifecycle", "warn: [Shutdown] Failed to release daemon lock: {}", e);
1870	}
1871
1872	dev_log!("lifecycle", "[Shutdown] All services stopped");
1873	dev_log!("lifecycle", "[Shutdown] Air Daemon has shut down gracefully");
1874	dev_log!("lifecycle", "===========================================");
1875
1876	Ok(())
1877}
1878
1879/// Validate the runtime environment before starting the daemon
1880///
1881/// # FUTURE Enhancements
1882/// - Check disk space availability
1883/// - Validate network connectivity
1884/// - Check file system permissions
1885/// - Verify required executables exist
1886/// - Validate system resources (CPU, RAM)
1887async fn validate_environment() -> Result<(), String> {
1888	// Validate OS and architecture
1889	dev_log!(
1890		"lifecycle",
1891		"[Environment] OS: {}, Arch: {}",
1892		std::env::consts::OS,
1893		std::env::consts::ARCH
1894	);
1895
1896	// Validate required environment variables
1897	if let Ok(home) = std::env::var("HOME") {
1898		if home.is_empty() {
1899			return Err("HOME environment variable is not set".to_string());
1900		}
1901	}
1902
1903	// Verify we can create lock files
1904	let lock_path = "/tmp/Air-test-lock.tmp";
1905	if std::fs::write(lock_path, b"test").is_err() {
1906		return Err("Cannot write to /tmp directory".to_string());
1907	}
1908	let _ = std::fs::remove_file(lock_path);
1909
1910	Ok(())
1911}
1912
1913/// Validate critical configuration values
1914///
1915/// # FUTURE Enhancements
1916/// - Add comprehensive configuration validation
1917/// - Validate port ranges
1918/// - Validate timeout values
1919/// - Validate file paths exist or are creatable
1920/// - Validate URLs are properly formatted
1921fn validate_configuration(_config:&AirConfiguration) -> Result<(), String> {
1922	// Add configuration validation logic here
1923	dev_log!("lifecycle", "[Config] Configuration passed basic validation");
1924	Ok(())
1925}
1926
1927#[tokio::main]
1928async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { Main().await }