Skip to main content

Air/
Binary.rs

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