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] [Logging] Initialize logging system
1295	// -------------------------------------------------------------------------
1296	InitializeLogging();
1297
1298	dev_log!("lifecycle", "[Boot] ===========================================");
1299	dev_log!("lifecycle", "[Boot] Starting Air Daemon");
1300	dev_log!("lifecycle", "[Boot] ===========================================");
1301	dev_log!(
1302		"lifecycle",
1303		"[Boot] Version: {} ({})",
1304		env!("CARGO_PKG_VERSION"),
1305		env!("CARGO_PKG_NAME")
1306	);
1307	let build_timestamp = env::var("BUILD_TIMESTAMP").unwrap_or_else(|_| "unknown".to_string());
1308	dev_log!("lifecycle", "[Boot] Build: {}", build_timestamp);
1309	dev_log!(
1310		"lifecycle",
1311		"[Boot] Target: {}-{}",
1312		std::env::consts::OS,
1313		std::env::consts::ARCH
1314	);
1315
1316	// -------------------------------------------------------------------------
1317	// [Boot] [Environment] Validate environment before starting
1318	// -------------------------------------------------------------------------
1319	dev_log!("lifecycle", "[Boot] Validating environment...");
1320
1321	if let Err(e) = validate_environment().await {
1322		dev_log!("lifecycle", "error: [Boot] Environment validation failed: {}", e);
1323		return Err(format!("Environment validation failed: {}", e).into());
1324	}
1325
1326	dev_log!("lifecycle", "[Boot] Environment validation passed");
1327
1328	// -------------------------------------------------------------------------
1329	// [Boot] [Observability] Initialize metrics and tracing
1330	// -------------------------------------------------------------------------
1331	Trace!("[Boot] [Observability] Initializing observability systems...");
1332
1333	// Initialize metrics with error handling
1334	if let Err(e) = Metrics::InitializeMetrics() {
1335		dev_log!("lifecycle", "error: [Boot] Failed to initialize metrics: {}", e);
1336		// Non-fatal: continue without metrics
1337	} else {
1338		dev_log!("lifecycle", "[Boot] [Observability] Metrics system initialized");
1339	}
1340
1341	// Initialize tracing with error handling
1342	if let Err(e) = Tracing::initialize_tracing(None) {
1343		dev_log!("lifecycle", "error: [Boot] Failed to initialize tracing: {}", e);
1344		// Non-fatal: continue without tracing
1345	} else {
1346		dev_log!("lifecycle", "[Boot] [Observability] Tracing system initialized");
1347	}
1348
1349	dev_log!("lifecycle", "[Boot] [Observability] Observability systems initialized");
1350
1351	// -------------------------------------------------------------------------
1352	// [Boot] [Args] Parse command line arguments
1353	// -------------------------------------------------------------------------
1354	Trace!("[Boot] [Args] Parsing command line arguments...");
1355
1356	let (config_path, bind_address, cli_command) = ParseArguments();
1357
1358	// If a CLI command was provided, handle it and exit
1359	if let Some(cmd) = cli_command {
1360		dev_log!("lifecycle", "[Boot] CLI command detected, executing...");
1361		let result = HandleCommand(cmd).await;
1362
1363		match &result {
1364			Ok(_) => {
1365				dev_log!("lifecycle", "[Boot] CLI command completed successfully");
1366				std::process::exit(0);
1367			},
1368			Err(e) => {
1369				dev_log!("lifecycle", "error: [Boot] CLI command failed: {}", e);
1370				std::process::exit(1);
1371			},
1372		}
1373	}
1374
1375	// -------------------------------------------------------------------------
1376	// [Boot] [Configuration] Load configuration
1377	// -------------------------------------------------------------------------
1378	Trace!("[Boot] [Configuration] Loading configuration...");
1379
1380	let config_manager = match ConfigurationManager::New(config_path) {
1381		Ok(cm) => cm,
1382		Err(e) => {
1383			dev_log!("lifecycle", "error: [Boot] Failed to create configuration manager: {}", e);
1384			return Err(format!("Configuration manager initialization failed: {}", e).into());
1385		},
1386	};
1387
1388	// Load configuration with timeout
1389	let configuration:std::sync::Arc<AirLibrary::Configuration::AirConfiguration> =
1390		match tokio::time::timeout(Duration::from_secs(10), config_manager.LoadConfiguration()).await {
1391			Ok(Ok(config)) => {
1392				dev_log!("lifecycle", "[Boot] [Configuration] Configuration loaded successfully");
1393				std::sync::Arc::new(config)
1394			},
1395			Ok(Err(e)) => {
1396				dev_log!("lifecycle", "error: [Boot] Failed to load configuration: {}", e);
1397				return Err(format!("Configuration load failed: {}", e).into());
1398			},
1399			Err(_) => {
1400				dev_log!("lifecycle", "error: [Boot] Configuration load timed out");
1401				return Err("Configuration load timed out".into());
1402			},
1403		};
1404
1405	// Validate critical configuration values
1406	validate_configuration(&configuration)?;
1407
1408	// -------------------------------------------------------------------------
1409	// [Boot] [Daemon] Initialize daemon lifecycle management
1410	// -------------------------------------------------------------------------
1411	Trace!("[Boot] [Daemon] Initializing daemon lifecycle management...");
1412
1413	let daemon_manager = match DaemonManager::New(None) {
1414		Ok(dm) => dm,
1415		Err(e) => {
1416			dev_log!("lifecycle", "error: [Boot] Failed to create daemon manager: {}", e);
1417			return Err(format!("Daemon manager initialization failed: {}", e).into());
1418		},
1419	};
1420
1421	// Acquire daemon lock to ensure single instance with timeout
1422	match tokio::time::timeout(Duration::from_secs(5), daemon_manager.AcquireLock()).await {
1423		Ok(Ok(_)) => {
1424			dev_log!("lifecycle", "[Boot] [Daemon] Daemon lock acquired successfully");
1425		},
1426		Ok(Err(e)) => {
1427			dev_log!("lifecycle", "error: [Boot] Failed to acquire daemon lock: {}", e);
1428			dev_log!("lifecycle", "error: [Boot] Another instance may already be running");
1429			return Err(format!("Daemon lock acquisition failed: {}", e).into());
1430		},
1431		Err(_) => {
1432			dev_log!("lifecycle", "error: [Boot] Daemon lock acquisition timed out");
1433			return Err("Daemon lock acquisition timed out".into());
1434		},
1435	}
1436
1437	// -------------------------------------------------------------------------
1438	// [Boot] [Health] Initialize health check system
1439	// -------------------------------------------------------------------------
1440	Trace!("[Boot] [Health] Initializing health check system...");
1441
1442	let health_manager:std::sync::Arc<HealthCheckManager> = Arc::new(HealthCheckManager::new(None));
1443
1444	dev_log!("lifecycle", "[Boot] [Health] Health check system initialized");
1445
1446	// -------------------------------------------------------------------------
1447	// [Boot] [State] Initialize application state
1448	// -------------------------------------------------------------------------
1449	Trace!("[Boot] [State] Initializing application state...");
1450
1451	let AppState:std::sync::Arc<ApplicationState> =
1452		match tokio::time::timeout(Duration::from_secs(10), ApplicationState::New(configuration.clone())).await {
1453			Ok(Ok(state)) => {
1454				dev_log!("lifecycle", "[Boot] [State] Application state initialized");
1455				Arc::new(state)
1456			},
1457			Ok(Err(e)) => {
1458				dev_log!("lifecycle", "error: [Boot] Failed to initialize application state: {}", e);
1459				// Attempt to release lock before returning
1460				let _ = daemon_manager.ReleaseLock().await;
1461				return Err(format!("Application state initialization failed: {}", e).into());
1462			},
1463			Err(_) => {
1464				dev_log!("lifecycle", "error: [Boot] Application state initialization timed out");
1465				let _ = daemon_manager.ReleaseLock().await;
1466				return Err("Application state initialization timed out".into());
1467			},
1468		};
1469
1470	// -------------------------------------------------------------------------
1471	// [Boot] [Services] Initialize core services
1472	// -------------------------------------------------------------------------
1473	Trace!("[Boot] [Services] Initializing core services...");
1474
1475	// Initialize each service with error handling
1476	let auth_service:std::sync::Arc<AuthenticationService> =
1477		match tokio::time::timeout(Duration::from_secs(10), AuthenticationService::new(AppState.clone())).await {
1478			Ok(Ok(svc)) => Arc::new(svc),
1479			Ok(Err(e)) => {
1480				dev_log!("lifecycle", "error: [Boot] Failed to initialize authentication service: {}", e);
1481				return Err(format!("Authentication service initialization failed: {}", e).into());
1482			},
1483			Err(_) => {
1484				dev_log!("lifecycle", "error: [Boot] Authentication service initialization timed out");
1485				return Err("Authentication service initialization timed out".into());
1486			},
1487		};
1488
1489	let update_manager:std::sync::Arc<UpdateManager> =
1490		match tokio::time::timeout(Duration::from_secs(10), UpdateManager::new(AppState.clone())).await {
1491			Ok(Ok(svc)) => Arc::new(svc),
1492			Ok(Err(e)) => {
1493				dev_log!("lifecycle", "error: [Boot] Failed to initialize update manager: {}", e);
1494				return Err(format!("Update manager initialization failed: {}", e).into());
1495			},
1496			Err(_) => {
1497				dev_log!("lifecycle", "error: [Boot] Update manager initialization timed out");
1498				return Err("Update manager initialization timed out".into());
1499			},
1500		};
1501
1502	let download_manager:std::sync::Arc<DownloadManager> =
1503		match tokio::time::timeout(Duration::from_secs(10), DownloadManager::new(AppState.clone())).await {
1504			Ok(Ok(svc)) => Arc::new(svc),
1505			Ok(Err(e)) => {
1506				dev_log!("lifecycle", "error: [Boot] Failed to initialize download manager: {}", e);
1507				return Err(format!("Download manager initialization failed: {}", e).into());
1508			},
1509			Err(_) => {
1510				dev_log!("lifecycle", "error: [Boot] Download manager initialization timed out");
1511				return Err("Download manager initialization timed out".into());
1512			},
1513		};
1514
1515	let file_indexer:std::sync::Arc<FileIndexer> =
1516		match tokio::time::timeout(Duration::from_secs(10), FileIndexer::new(AppState.clone())).await {
1517			Ok(Ok(svc)) => Arc::new(svc),
1518			Ok(Err(e)) => {
1519				dev_log!("lifecycle", "error: [Boot] Failed to initialize file indexer: {}", e);
1520				return Err(format!("File indexer initialization failed: {}", e).into());
1521			},
1522			Err(_) => {
1523				dev_log!("lifecycle", "error: [Boot] File indexer initialization timed out");
1524				return Err("File indexer initialization timed out".into());
1525			},
1526		};
1527
1528	dev_log!("lifecycle", "[Boot] [Services] All core services initialized successfully");
1529
1530	// -------------------------------------------------------------------------
1531	// [Boot] [Health] Register services for health monitoring
1532	// -------------------------------------------------------------------------
1533	Trace!("[Boot] [Health] Registering services for health monitoring...");
1534
1535	// Register each service with validation
1536	let service_registrations = vec![
1537		("authentication", HealthCheckLevel::Functional),
1538		("updates", HealthCheckLevel::Functional),
1539		("downloader", HealthCheckLevel::Functional),
1540		("indexing", HealthCheckLevel::Functional),
1541		("grpc", HealthCheckLevel::Responsive),
1542		("connections", HealthCheckLevel::Alive),
1543	];
1544
1545	for (service_name, level) in service_registrations {
1546		match tokio::time::timeout(
1547			Duration::from_secs(5),
1548			health_manager.RegisterService(service_name.to_string(), level),
1549		)
1550		.await
1551		{
1552			Ok(result) => {
1553				match result {
1554					Ok(_) => {
1555						dev_log!("lifecycle", "[Boot] [Health] Registered service: {}", service_name);
1556					},
1557					Err(e) => {
1558						dev_log!("lifecycle", "warn: [Boot] Failed to register service {}: {}", service_name, e);
1559						// Non-fatal: continue without this service's health
1560						// checks
1561					},
1562				}
1563			},
1564			Err(_) => {
1565				dev_log!("lifecycle", "warn: [Boot] Service registration timed out: {}", service_name);
1566			},
1567		}
1568	}
1569
1570	dev_log!("lifecycle", "[Boot] [Health] Service health monitoring configured");
1571
1572	// -------------------------------------------------------------------------
1573	// [Boot] [Vine] Initialize gRPC server
1574	// -------------------------------------------------------------------------
1575	Trace!("[Boot] [Vine] Initializing gRPC server...");
1576
1577	// Parse bind address with validation
1578	let bind_addr:SocketAddr = match bind_address {
1579		Some(addr) => {
1580			match addr.parse() {
1581				Ok(parsed) => {
1582					dev_log!("lifecycle", "[Boot] [Vine] Using custom bind address: {}", parsed);
1583					parsed
1584				},
1585				Err(e) => {
1586					dev_log!("lifecycle", "error: [Boot] Invalid bind address '{}': {}", addr, e);
1587					return Err(format!("Invalid bind address: {}", e).into());
1588				},
1589			}
1590		},
1591		None => {
1592			match DefaultBindAddress.parse() {
1593				Ok(parsed) => parsed,
1594				Err(e) => {
1595					dev_log!(
1596						"lifecycle",
1597						"error: [Boot] Invalid default bind address '{}': {}",
1598						DefaultBindAddress,
1599						e
1600					);
1601					return Err(format!("Invalid default bind address: {}", e).into());
1602				},
1603			}
1604		},
1605	};
1606
1607	dev_log!("lifecycle", "[Boot] [Vine] Configuring gRPC server on {}", bind_addr);
1608
1609	// Create gRPC service implementation with all dependencies
1610	let vine_service = AirVinegRPCService::new(
1611		AppState.clone(),
1612		auth_service.clone(),
1613		update_manager.clone(),
1614		download_manager.clone(),
1615		file_indexer.clone(),
1616	);
1617
1618	// Create a oneshot channel to signal server shutdown
1619	let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
1620
1621	// Spawn the tonic gRPC server with panic handling
1622	let server_handle:tokio::task::JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> =
1623		tokio::spawn(async move {
1624			dev_log!("lifecycle", "[Vine] Starting gRPC server on {}", bind_addr);
1625
1626			let svc = AirServiceServer::new(vine_service);
1627
1628			let server = tonic::transport::Server::builder()
1629				.add_service(svc)
1630				.serve_with_shutdown(bind_addr, async {
1631					// Wait for shutdown signal from main
1632					let _ = shutdown_rx.await;
1633					dev_log!("lifecycle", "[Vine] Shutdown signal received, stopping server...");
1634				});
1635
1636			dev_log!("lifecycle", "[Vine] gRPC server listening on {}", bind_addr);
1637
1638			match server.await {
1639				Ok(_) => {
1640					dev_log!("lifecycle", "[Vine] gRPC server stopped cleanly");
1641					Ok(())
1642				},
1643				Err(e) => {
1644					dev_log!("grpc", "error: [Vine] gRPC server error: {}", e);
1645					Err(e.into())
1646				},
1647			}
1648		});
1649
1650	// Wait a bit for the server to start
1651	tokio::time::sleep(Duration::from_millis(100)).await;
1652
1653	// Check if server task panicked or failed early
1654	if server_handle.is_finished() {
1655		dev_log!("lifecycle", "error: [Boot] gRPC server failed to start");
1656		let _ = daemon_manager.ReleaseLock().await;
1657		return Err("gRPC server failed to start".into());
1658	}
1659
1660	// -------------------------------------------------------------------------
1661	// [Boot] [Monitoring] Start background monitoring tasks
1662	// -------------------------------------------------------------------------
1663	Trace!("[Boot] [Monitoring] Starting background monitoring tasks...");
1664
1665	// Start connection monitoring background task
1666	let connection_monitor_handle:tokio::task::JoinHandle<()> = tokio::spawn({
1667		let AppState = AppState.clone();
1668		let health_manager = health_manager.clone();
1669		async move {
1670			let mut interval = interval(Duration::from_secs(60)); // Check every minute
1671			loop {
1672				interval.tick().await;
1673
1674				// Update resource usage with error handling
1675				if let Err(e) = AppState.UpdateResourceUsage().await {
1676					dev_log!("lifecycle", "warn: [ConnectionMonitor] Failed to update resource usage: {}", e);
1677				}
1678
1679				// Get resource metrics
1680				let resources = AppState.GetResourceUsage().await;
1681
1682				// Record metrics
1683				let metrics_collector = Metrics::GetMetrics();
1684				metrics_collector.UpdateResourceMetrics(
1685					(resources.MemoryUsageMb * 1024.0 * 1024.0) as u64, // Convert MB to bytes
1686					resources.CPUUsagePercent,
1687					AppState.GetActiveConnectionCount().await as u64,
1688					0, // Thread count: Requires tokio runtime metrics integration
1689				);
1690
1691				// Clean up stale connections (5 minute timeout)
1692				if let Err(e) = AppState.CleanupStaleConnections(300).await {
1693					dev_log!(
1694						"lifecycle",
1695						"warn: [ConnectionMonitor] Failed to cleanup stale connections: {}",
1696						e
1697					);
1698				}
1699
1700				// Perform health checks
1701				match health_manager.CheckService("connections").await {
1702					Ok(_) => {},
1703					Err(e) => {
1704						dev_log!("lifecycle", "warn: [ConnectionMonitor] Health check failed: {}", e);
1705
1706						// Record metrics for failed health check
1707						let metrics_collector = Metrics::GetMetrics();
1708						metrics_collector.RecordRequestFailure("health_check_failed", 0.0);
1709					},
1710				}
1711
1712				dev_log!(
1713					"lifecycle",
1714					"[ConnectionMonitor] Active connections: {}",
1715					AppState.GetActiveConnectionCount().await
1716				);
1717			}
1718		}
1719	});
1720
1721	// Register background task with error handling
1722	if let Err(e) = AppState.RegisterBackgroundTask(connection_monitor_handle).await {
1723		dev_log!("lifecycle", "warn: [Boot] Failed to register connection monitor: {}", e);
1724		// Non-fatal: continue monitoring may not be tracked
1725	}
1726
1727	// Start health monitoring background task
1728	let health_monitor_handle:tokio::task::JoinHandle<()> = tokio::spawn({
1729		let health_manager = health_manager.clone();
1730		async move {
1731			let mut interval = interval(Duration::from_secs(30)); // Check every 30 seconds
1732			loop {
1733				interval.tick().await;
1734
1735				// Perform comprehensive health checks
1736				let services = ["authentication", "updates", "downloader", "indexing", "grpc"];
1737				for service in services.iter() {
1738					if let Err(e) = health_manager.CheckService(service).await {
1739						dev_log!("lifecycle", "warn: [HealthMonitor] Health check failed for {}: {}", service, e);
1740					}
1741				}
1742
1743				// Log overall health status
1744				let overall_health = health_manager.GetOverallHealth().await;
1745				dev_log!("lifecycle", "[HealthMonitor] Overall health: {:?}", overall_health);
1746			}
1747		}
1748	});
1749
1750	// Register health monitoring task with error handling
1751	if let Err(e) = AppState.RegisterBackgroundTask(health_monitor_handle).await {
1752		dev_log!("lifecycle", "warn: [Boot] Failed to register health monitor: {}", e);
1753		// Non-fatal: continue monitoring may not be tracked
1754	}
1755
1756	// -------------------------------------------------------------------------
1757	// [Boot] [Startup] Start services
1758	// -------------------------------------------------------------------------
1759	Trace!("[Boot] [Startup] Starting background services...");
1760
1761	// Start background tasks for services that support it
1762	let _ = auth_service.StartBackgroundTasks().await?;
1763	let _ = update_manager.StartBackgroundTasks().await?;
1764	let _ = download_manager.StartBackgroundTasks().await?;
1765	// FileIndexer does not have background tasks, it's used directly
1766	let _indexing_handle = None::<tokio::task::JoinHandle<()>>;
1767
1768	dev_log!("lifecycle", "[Boot] [Startup] All services started successfully");
1769
1770	// -------------------------------------------------------------------------
1771	// [Runtime] Run server and wait for shutdown
1772	// -------------------------------------------------------------------------
1773	dev_log!("lifecycle", "===========================================");
1774	dev_log!("lifecycle", "[Runtime] Air Daemon is now running");
1775	dev_log!("lifecycle", "[Runtime] Listening on {} for Mountain connections", bind_addr);
1776	dev_log!("lifecycle", "[Runtime] Protocol Version: {}", ProtocolVersion);
1777	dev_log!("lifecycle", "[Runtime] Cocoon Port: 50052");
1778	dev_log!("lifecycle", "===========================================");
1779	dev_log!("lifecycle", "");
1780	dev_log!("lifecycle", "Running. Press Ctrl+C to stop.");
1781	dev_log!("lifecycle", "");
1782
1783	// Wait for shutdown signal
1784	WaitForShutdownSignal().await;
1785
1786	// Signal gRPC server to shut down
1787	dev_log!("lifecycle", "[Shutdown] Signaling gRPC server to stop...");
1788	let _ = shutdown_tx.send(());
1789
1790	// Await the server task to finish with timeout
1791	match tokio::time::timeout(Duration::from_secs(30), server_handle).await {
1792		Ok(Ok(Ok(_))) => {
1793			dev_log!("lifecycle", "[Shutdown] gRPC server stopped normally");
1794		},
1795		Ok(Ok(Err(e))) => {
1796			dev_log!("lifecycle", "warn: [Shutdown] gRPC server stopped with error: {}", e);
1797		},
1798		Ok(Err(e)) => {
1799			dev_log!("lifecycle", "warn: [Shutdown] gRPC server task panicked: {:?}", e);
1800		},
1801		Err(_) => {
1802			dev_log!("lifecycle", "warn: [Shutdown] gRPC server shutdown timed out");
1803		},
1804	}
1805
1806	// -------------------------------------------------------------------------
1807	// [Shutdown] Graceful shutdown
1808	// -------------------------------------------------------------------------
1809	dev_log!("lifecycle", "===========================================");
1810	dev_log!("lifecycle", "[Shutdown] Initiating graceful shutdown...");
1811	dev_log!("lifecycle", "===========================================");
1812
1813	// Stop all background tasks with timeout
1814	dev_log!("lifecycle", "[Shutdown] Stopping background tasks...");
1815	if let Err(_) =
1816		tokio::time::timeout(Duration::from_secs(10), async { AppState.StopAllBackgroundTasks().await }).await
1817	{
1818		dev_log!("lifecycle", "warn: [Shutdown] Background tasks stop timed out or failed");
1819	}
1820
1821	// Stop background services
1822	dev_log!("lifecycle", "[Shutdown] Stopping background services...");
1823	auth_service.StopBackgroundTasks().await;
1824	update_manager.StopBackgroundTasks().await;
1825	download_manager.StopBackgroundTasks().await;
1826
1827	// Log final statistics
1828	dev_log!("lifecycle", "[Shutdown] Collecting final statistics...");
1829
1830	let metrics = AppState.GetMetrics().await;
1831	let resources = AppState.GetResourceUsage().await;
1832	let health_stats:HealthStatistics = health_manager.GetHealthStatistics().await;
1833
1834	// Get final metrics data
1835	let metrics_data = Metrics::GetMetrics().GetMetricsData();
1836
1837	dev_log!("lifecycle", "===========================================");
1838	dev_log!("lifecycle", "[Shutdown] Final Statistics");
1839	dev_log!("lifecycle", "===========================================");
1840	dev_log!("lifecycle", "[Shutdown] Requests:");
1841	dev_log!("lifecycle", " - Successful: {}", metrics.SuccessfulRequest);
1842	dev_log!("lifecycle", " - Failed: {}", metrics.FailedRequest);
1843	dev_log!("lifecycle", "[Shutdown] Metrics:");
1844	dev_log!("lifecycle", "  - Success rate: {:.2}%", metrics_data.SuccessRate());
1845	dev_log!("lifecycle", "  - Error rate: {:.2}%", metrics_data.ErrorRate());
1846	dev_log!("lifecycle", "[Shutdown] Resources:");
1847	dev_log!("lifecycle", "  - Memory: {:.2} MB", resources.MemoryUsageMb);
1848	dev_log!("lifecycle", "  - CPU: {:.2}%", resources.CPUUsagePercent);
1849	dev_log!("lifecycle", "[Shutdown] Health:");
1850	dev_log!("lifecycle", "  - Overall: {:.2}%", health_stats.OverallHealthPercentage());
1851	dev_log!(
1852		"lifecycle",
1853		"  - Healthy services: {}/{}",
1854		health_stats.HealthyServices,
1855		health_stats.TotalServices
1856	);
1857	dev_log!("lifecycle", "===========================================");
1858
1859	// Release daemon lock
1860	dev_log!("lifecycle", "[Shutdown] Releasing daemon lock...");
1861	if let Err(e) = daemon_manager.ReleaseLock().await {
1862		dev_log!("lifecycle", "warn: [Shutdown] Failed to release daemon lock: {}", e);
1863	}
1864
1865	dev_log!("lifecycle", "[Shutdown] All services stopped");
1866	dev_log!("lifecycle", "[Shutdown] Air Daemon has shut down gracefully");
1867	dev_log!("lifecycle", "===========================================");
1868
1869	Ok(())
1870}
1871
1872/// Validate the runtime environment before starting the daemon
1873///
1874/// # FUTURE Enhancements
1875/// - Check disk space availability
1876/// - Validate network connectivity
1877/// - Check file system permissions
1878/// - Verify required executables exist
1879/// - Validate system resources (CPU, RAM)
1880async fn validate_environment() -> Result<(), String> {
1881	// Validate OS and architecture
1882	dev_log!(
1883		"lifecycle",
1884		"[Environment] OS: {}, Arch: {}",
1885		std::env::consts::OS,
1886		std::env::consts::ARCH
1887	);
1888
1889	// Validate required environment variables
1890	if let Ok(home) = std::env::var("HOME") {
1891		if home.is_empty() {
1892			return Err("HOME environment variable is not set".to_string());
1893		}
1894	}
1895
1896	// Verify we can create lock files
1897	let lock_path = "/tmp/Air-test-lock.tmp";
1898	if std::fs::write(lock_path, b"test").is_err() {
1899		return Err("Cannot write to /tmp directory".to_string());
1900	}
1901	let _ = std::fs::remove_file(lock_path);
1902
1903	Ok(())
1904}
1905
1906/// Validate critical configuration values
1907///
1908/// # FUTURE Enhancements
1909/// - Add comprehensive configuration validation
1910/// - Validate port ranges
1911/// - Validate timeout values
1912/// - Validate file paths exist or are creatable
1913/// - Validate URLs are properly formatted
1914fn validate_configuration(_config:&AirConfiguration) -> Result<(), String> {
1915	// Add configuration validation logic here
1916	dev_log!("lifecycle", "[Config] Configuration passed basic validation");
1917	Ok(())
1918}
1919
1920#[tokio::main]
1921async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { Main().await }