1use std::collections::HashMap;
4use std::path::Path;
5use std::sync::Arc;
6use std::time::Duration;
7
8use async_trait::async_trait;
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11use tokio::sync::{broadcast, Mutex, RwLock};
12use tokio::time::{interval, timeout};
13use uuid::Uuid;
14
15use crate::auth::{
16 AccountManager, MemorySessionStore, MemoryUserStore, SecurityPolicy, User, UserSession,
17};
18#[cfg(not(target_arch = "wasm32"))]
19use crate::concurrency::ConcurrencyManager;
20use crate::config::{ConfigurationTier, MemoryConfigStore, TieredConfigManager};
21use crate::error::{Error, ErrorKind, Result}; use crate::event::EventBusManager;
23#[cfg(not(target_arch = "wasm32"))]
24use crate::file::FileManager;
25#[cfg(not(target_arch = "wasm32"))]
26use crate::logging::LoggingManager;
27use crate::manager::{HealthStatus, ManagedState, Manager, ManagerState, ManagerStatus};
28use crate::platform::PlatformManager;
29use crate::plugin::PluginManager;
30#[cfg(not(target_arch = "wasm32"))]
31use crate::task::TaskManager;
32use crate::ui::UILayoutManager;
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35pub enum ApplicationState {
36 Created,
37 Initializing,
38 Running,
39 ShuttingDown,
40 Shutdown,
41 Error,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct ApplicationHealth {
46 pub status: HealthStatus,
47 pub uptime: Duration,
48 pub managers: HashMap<String, HealthStatus>,
49 pub last_check: DateTime<Utc>,
50 pub details: HashMap<String, serde_json::Value>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct ApplicationStats {
55 pub version: String,
56 pub started_at: DateTime<Utc>,
57 pub uptime: Duration,
58 pub state: ApplicationState,
59 pub manager_count: usize,
60 pub initialized_managers: usize,
61 pub failed_managers: usize,
62 pub memory_usage_bytes: u64,
63 pub cpu_usage_percent: f64,
64 pub system_info: SystemInfo,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct SystemInfo {
69 pub os_name: String,
70 pub os_version: String,
71 pub arch: String,
72 pub cpu_cores: usize,
73 pub total_memory_bytes: u64,
74 pub available_memory_bytes: u64,
75 pub hostname: String,
76}
77
78impl SystemInfo {
79 pub fn collect() -> Self {
80 Self {
81 os_name: std::env::consts::OS.to_string(),
82 os_version: "1.0".to_string(),
83 arch: std::env::consts::ARCH.to_string(),
84 cpu_cores: num_cpus::get(),
85 total_memory_bytes: 0,
86 available_memory_bytes: 0,
87 hostname: hostname::get()
88 .unwrap_or_default()
89 .to_string_lossy()
90 .to_string(),
91 }
92 }
93}
94
95pub struct ApplicationCore {
97 state: ManagedState,
98 app_state: Arc<RwLock<ApplicationState>>,
99 started_at: DateTime<Utc>,
100
101 platform_manager: Option<PlatformManager>,
103
104 config_manager: Option<Arc<Mutex<TieredConfigManager>>>,
106
107 logging_manager: Option<LoggingManager>,
109 account_manager: Option<AccountManager>,
110
111 event_bus_manager: Option<Arc<EventBusManager>>,
113 file_manager: Option<FileManager>,
114 concurrency_manager: Option<ConcurrencyManager>,
115 task_manager: Option<TaskManager>,
116
117 plugin_manager: Option<PluginManager>,
119 ui_layout_manager: Option<UILayoutManager>,
120
121 shutdown_signal: broadcast::Sender<()>,
123 health_check_interval: Duration,
124
125 current_user: Arc<RwLock<Option<User>>>,
127 current_session: Arc<RwLock<Option<UserSession>>>,
128
129 system_info: SystemInfo,
131 manager_registry: HashMap<String, Box<dyn Manager>>,
132}
133
134impl std::fmt::Debug for ApplicationCore {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 f.debug_struct("ApplicationCore")
137 .field("started_at", &self.started_at)
138 .field("system_info", &self.system_info)
139 .finish()
140 }
141}
142
143impl ApplicationCore {
144 pub fn new() -> Self {
146 let (shutdown_signal, _) = broadcast::channel(1);
147
148 Self {
149 state: ManagedState::new(Uuid::new_v4(), "application_core"),
150 app_state: Arc::new(RwLock::new(ApplicationState::Created)),
151 started_at: Utc::now(),
152 platform_manager: None,
153 config_manager: None,
154 logging_manager: None,
155 account_manager: None,
156 event_bus_manager: None,
157 file_manager: None,
158 concurrency_manager: None,
159 task_manager: None,
160 plugin_manager: None,
161 ui_layout_manager: None,
162 shutdown_signal,
163 health_check_interval: Duration::from_secs(30),
164 current_user: Arc::new(RwLock::new(None)),
165 current_session: Arc::new(RwLock::new(None)),
166 system_info: SystemInfo::collect(),
167 manager_registry: HashMap::new(),
168 }
169 }
170
171 pub fn with_config_file(_config_path: impl AsRef<Path>) -> Self {
173 Self::new()
177 }
178
179 pub async fn initialize(&mut self) -> Result<()> {
181 *self.app_state.write().await = ApplicationState::Initializing;
182 self.state.set_state(ManagerState::Initializing).await;
183
184 tracing::info!("Starting Qorzen application initialization");
185
186 self.init_platform_manager().await?;
188
189 self.init_config_manager().await?;
191
192 self.init_logging_manager().await?;
194
195 self.init_concurrency_manager().await?;
197 self.init_event_bus_manager().await?;
198 self.init_file_manager().await?;
199 self.init_task_manager().await?;
200
201 self.init_account_manager().await?;
203
204 self.init_ui_layout_manager().await?;
206 self.init_plugin_manager().await?;
207
208 self.start_background_services().await?;
210
211 self.setup_signal_handlers().await?;
213
214 *self.app_state.write().await = ApplicationState::Running;
215 self.state.set_state(ManagerState::Running).await;
216
217 tracing::info!("Qorzen application initialization complete");
218 Ok(())
219 }
220
221 async fn init_platform_manager(&mut self) -> Result<()> {
222 tracing::info!("Initializing platform manager");
223 let mut platform_manager = PlatformManager::new()?;
224 platform_manager.initialize().await?;
225 self.platform_manager = Some(platform_manager);
226 Ok(())
227 }
228
229 async fn init_config_manager(&mut self) -> Result<()> {
230 tracing::info!("Initializing configuration manager");
231 let mut config_manager = TieredConfigManager::new();
232
233 config_manager.add_store(
235 ConfigurationTier::System,
236 Box::new(MemoryConfigStore::new(ConfigurationTier::System)),
237 );
238 config_manager.add_store(
239 ConfigurationTier::Runtime,
240 Box::new(MemoryConfigStore::new(ConfigurationTier::Runtime)),
241 );
242
243 config_manager.initialize().await?;
244 self.config_manager = Some(Arc::new(Mutex::new(config_manager)));
245 Ok(())
246 }
247
248 async fn init_logging_manager(&mut self) -> Result<()> {
249 tracing::info!("Initializing logging manager");
250 let config = if let Some(config_manager) = &self.config_manager {
251 let manager = config_manager.lock().await;
253 manager
254 .get("logging")
255 .await
256 .unwrap_or(None)
257 .unwrap_or_else(crate::config::LoggingConfig::default)
258 } else {
259 crate::config::LoggingConfig::default()
260 };
261
262 let mut logging_manager = LoggingManager::new(config);
263 logging_manager.initialize().await?;
264 self.logging_manager = Some(logging_manager);
265 Ok(())
266 }
267
268 async fn init_concurrency_manager(&mut self) -> Result<()> {
269 tracing::info!("Initializing concurrency manager");
270 let config = if let Some(config_manager) = &self.config_manager {
271 let manager = config_manager.lock().await;
272 manager
273 .get("concurrency")
274 .await
275 .unwrap_or(None)
276 .unwrap_or_else(crate::config::ConcurrencyConfig::default)
277 } else {
278 crate::config::ConcurrencyConfig::default()
279 };
280
281 let mut concurrency_manager = ConcurrencyManager::new(config)?;
282 concurrency_manager.initialize().await?;
283 self.concurrency_manager = Some(concurrency_manager);
284 Ok(())
285 }
286
287 async fn init_event_bus_manager(&mut self) -> Result<()> {
288 tracing::info!("Initializing event bus manager");
289 let config = if let Some(config_manager) = &self.config_manager {
290 let manager = config_manager.lock().await;
291 manager
292 .get("event_bus")
293 .await
294 .unwrap_or(None)
295 .unwrap_or_default()
296 } else {
297 crate::config::EventBusConfig::default()
298 };
299
300 let event_config = crate::event::EventBusConfig {
301 worker_count: config.worker_count,
302 queue_capacity: config.queue_size,
303 default_timeout: Duration::from_millis(config.publish_timeout_ms),
304 enable_persistence: config.enable_persistence,
305 enable_metrics: config.enable_metrics,
306 batch_size: 100,
307 max_retry_delay: Duration::from_secs(60),
308 };
309
310 let mut event_bus_manager = EventBusManager::new(event_config);
311 event_bus_manager.initialize().await?;
312 self.event_bus_manager = Some(Arc::new(event_bus_manager));
313 Ok(())
314 }
315
316 async fn init_file_manager(&mut self) -> Result<()> {
317 tracing::info!("Initializing file manager");
318 let config = if let Some(config_manager) = &self.config_manager {
319 let manager = config_manager.lock().await;
320 manager
321 .get("files")
322 .await
323 .unwrap_or(None)
324 .unwrap_or_else(crate::config::FileConfig::default)
325 } else {
326 crate::config::FileConfig::default()
327 };
328
329 let mut file_manager = FileManager::new(config);
330
331 if let Some(event_bus) = &self.event_bus_manager {
333 file_manager.set_event_bus(Arc::clone(event_bus));
334 }
335
336 file_manager.initialize().await?;
337 self.file_manager = Some(file_manager);
338 Ok(())
339 }
340
341 async fn init_task_manager(&mut self) -> Result<()> {
342 tracing::info!("Initializing task manager");
343 let config = if let Some(config_manager) = &self.config_manager {
344 let manager = config_manager.lock().await;
345 manager
346 .get("tasks")
347 .await
348 .unwrap_or(None)
349 .unwrap_or_default()
350 } else {
351 crate::config::TaskConfig::default()
352 };
353
354 let mut task_manager = TaskManager::new(config);
355
356 if let Some(event_bus) = &self.event_bus_manager {
358 task_manager.set_event_bus(Arc::clone(event_bus));
359 }
360
361 task_manager.initialize().await?;
362 self.task_manager = Some(task_manager);
363 Ok(())
364 }
365
366 async fn init_account_manager(&mut self) -> Result<()> {
367 tracing::info!("Initializing account manager");
368 let security_policy = if let Some(config_manager) = &self.config_manager {
369 let manager = config_manager.lock().await;
370 manager
371 .get("security")
372 .await
373 .unwrap_or(None)
374 .unwrap_or_else(SecurityPolicy::default)
375 } else {
376 SecurityPolicy::default()
377 };
378
379 let session_store = Box::new(MemorySessionStore::new());
380 let user_store = Box::new(MemoryUserStore::new());
381
382 let mut account_manager = AccountManager::new(session_store, user_store, security_policy);
383 account_manager.initialize().await?;
384 self.account_manager = Some(account_manager);
385 Ok(())
386 }
387
388 async fn init_ui_layout_manager(&mut self) -> Result<()> {
389 tracing::info!("Initializing UI layout manager");
390 let mut ui_layout_manager = UILayoutManager::new();
391 ui_layout_manager.initialize().await?;
392 self.ui_layout_manager = Some(ui_layout_manager);
393 Ok(())
394 }
395
396 async fn init_plugin_manager(&mut self) -> Result<()> {
397 tracing::info!("Initializing plugin manager");
398
399 let loader = Box::new(SimplePluginLoader::new());
401 let mut plugin_manager = PluginManager::new(loader);
402 plugin_manager.initialize().await?;
403 self.plugin_manager = Some(plugin_manager);
404 Ok(())
405 }
406
407 async fn start_background_services(&self) -> Result<()> {
408 tracing::info!("Starting background services");
409
410 self.start_health_monitoring().await?;
412
413 if let Some(config_manager) = self.config_manager.as_ref().cloned() {
415 tokio::spawn(async move {
416 let mut interval = interval(Duration::from_secs(300));
417 loop {
418 interval.tick().await;
419 let result = {
420 let manager = config_manager.lock().await;
421 manager.sync().await
422 };
423
424 if let Err(e) = result {
425 tracing::error!("Configuration sync failed: {}", e);
426 }
427 }
428 });
429 }
430
431 Ok(())
432 }
433
434 async fn start_health_monitoring(&self) -> Result<()> {
435 let health_interval = self.health_check_interval;
436 let app_state = Arc::clone(&self.app_state);
437
438 tokio::spawn(async move {
439 let mut interval = interval(health_interval);
440
441 loop {
442 interval.tick().await;
443
444 let state = *app_state.read().await;
445 if state != ApplicationState::Running {
446 break;
447 }
448
449 tracing::debug!("Performing health check");
452 }
453 });
454
455 Ok(())
456 }
457
458 async fn setup_signal_handlers(&self) -> Result<()> {
459 let shutdown_sender = self.shutdown_signal.clone();
460 let app_state = Arc::clone(&self.app_state);
461
462 tokio::spawn(async move {
463 #[cfg(unix)]
464 {
465 use tokio::signal::unix::{signal, SignalKind};
466
467 let mut sigterm =
468 signal(SignalKind::terminate()).expect("Failed to register SIGTERM handler");
469 let mut sigint =
470 signal(SignalKind::interrupt()).expect("Failed to register SIGINT handler");
471
472 tokio::select! {
473 _ = sigterm.recv() => {
474 tracing::info!("Received SIGTERM, initiating graceful shutdown");
475 }
476 _ = sigint.recv() => {
477 tracing::info!("Received SIGINT, initiating graceful shutdown");
478 }
479 }
480 }
481
482 #[cfg(windows)]
483 {
484 use tokio::signal;
485
486 signal::ctrl_c().await.expect("Failed to listen for ctrl+c");
487 tracing::info!("Received Ctrl+C, initiating graceful shutdown");
488 }
489
490 #[cfg(target_arch = "wasm32")]
491 {
492 }
495
496 *app_state.write().await = ApplicationState::ShuttingDown;
497 let _ = shutdown_sender.send(());
498 });
499
500 Ok(())
501 }
502
503 pub async fn shutdown(&mut self) -> Result<()> {
505 *self.app_state.write().await = ApplicationState::ShuttingDown;
506 self.state.set_state(ManagerState::ShuttingDown).await;
507
508 tracing::info!("Shutting down Qorzen application");
509
510 if let Some(mut plugin_manager) = self.plugin_manager.take() {
512 let _ = timeout(Duration::from_secs(10), plugin_manager.shutdown()).await;
513 }
514
515 if let Some(mut ui_layout_manager) = self.ui_layout_manager.take() {
516 let _ = timeout(Duration::from_secs(5), ui_layout_manager.shutdown()).await;
517 }
518
519 if let Some(mut account_manager) = self.account_manager.take() {
520 let _ = timeout(Duration::from_secs(5), account_manager.shutdown()).await;
521 }
522
523 if let Some(mut task_manager) = self.task_manager.take() {
524 let _ = timeout(Duration::from_secs(10), task_manager.shutdown()).await;
525 }
526
527 if let Some(mut file_manager) = self.file_manager.take() {
528 let _ = timeout(Duration::from_secs(5), file_manager.shutdown()).await;
529 }
530
531 if let Some(event_bus_manager) = self.event_bus_manager.take() {
532 if let Ok(mut manager) = Arc::try_unwrap(event_bus_manager) {
533 let _ = timeout(Duration::from_secs(5), manager.shutdown()).await;
534 }
535 }
536
537 if let Some(mut concurrency_manager) = self.concurrency_manager.take() {
538 let _ = timeout(Duration::from_secs(10), concurrency_manager.shutdown()).await;
539 }
540
541 if let Some(mut logging_manager) = self.logging_manager.take() {
542 let _ = timeout(Duration::from_secs(5), logging_manager.shutdown()).await;
543 }
544
545 if let Some(config_manager) = self.config_manager.take() {
546 let mut manager = config_manager.lock().await;
547 let _ = timeout(Duration::from_secs(2), manager.shutdown()).await;
548 }
549
550 if let Some(mut platform_manager) = self.platform_manager.take() {
551 let _ = timeout(Duration::from_secs(5), platform_manager.shutdown()).await;
552 }
553
554 *self.app_state.write().await = ApplicationState::Shutdown;
555 self.state.set_state(ManagerState::Shutdown).await;
556
557 tracing::info!("Qorzen application shutdown complete");
558 Ok(())
559 }
560
561 pub async fn wait_for_shutdown(&self) -> Result<()> {
563 let mut receiver = self.shutdown_signal.subscribe();
564 receiver.recv().await.map_err(|_| {
565 Error::new(
566 ErrorKind::Application,
567 "Shutdown signal channel closed unexpectedly",
568 )
569 })?;
570 Ok(())
571 }
572
573 pub async fn get_health(&self) -> ApplicationHealth {
575 let mut manager_health = HashMap::new();
576 let mut overall_healthy = true;
577
578 if let Some(platform_manager) = &self.platform_manager {
580 let health = platform_manager.health_check().await;
581 if health != HealthStatus::Healthy {
582 overall_healthy = false;
583 }
584 manager_health.insert("platform_manager".to_string(), health);
585 }
586
587 if let Some(config_manager) = &self.config_manager {
588 let manager = config_manager.lock().await;
589 let health = manager.health_check().await;
590 if health != HealthStatus::Healthy {
591 overall_healthy = false;
592 }
593 manager_health.insert("config_manager".to_string(), health);
594 }
595
596 let overall_status = if overall_healthy {
599 HealthStatus::Healthy
600 } else {
601 HealthStatus::Degraded
602 };
603
604 ApplicationHealth {
605 status: overall_status,
606 uptime: Utc::now()
607 .signed_duration_since(self.started_at)
608 .to_std()
609 .unwrap_or_default(),
610 managers: manager_health,
611 last_check: Utc::now(),
612 details: HashMap::new(),
613 }
614 }
615
616 pub async fn get_stats(&self) -> ApplicationStats {
618 ApplicationStats {
619 version: crate::VERSION.to_string(),
620 started_at: self.started_at,
621 uptime: Utc::now()
622 .signed_duration_since(self.started_at)
623 .to_std()
624 .unwrap_or_default(),
625 state: *self.app_state.read().await,
626 manager_count: self.manager_registry.len(),
627 initialized_managers: self.manager_registry.len(), failed_managers: 0, memory_usage_bytes: 0, cpu_usage_percent: 0.0, system_info: self.system_info.clone(),
632 }
633 }
634
635 pub async fn current_user(&self) -> Option<User> {
637 self.current_user.read().await.clone()
638 }
639
640 pub async fn current_session(&self) -> Option<UserSession> {
642 self.current_session.read().await.clone()
643 }
644
645 pub async fn get_state(&self) -> ApplicationState {
647 *self.app_state.read().await
648 }
649}
650
651impl Default for ApplicationCore {
652 fn default() -> Self {
653 Self::new()
654 }
655}
656
657#[async_trait]
658impl Manager for ApplicationCore {
659 fn name(&self) -> &str {
660 "application_core"
661 }
662
663 fn id(&self) -> Uuid {
664 self.state.id()
665 }
666
667 async fn initialize(&mut self) -> Result<()> {
668 Ok(())
670 }
671
672 async fn shutdown(&mut self) -> Result<()> {
673 Ok(())
675 }
676
677 async fn status(&self) -> ManagerStatus {
678 let mut status = self.state.status().await;
679 let app_stats = self.get_stats().await;
680
681 status.add_metadata(
682 "app_state",
683 serde_json::Value::String(format!("{:?}", app_stats.state)),
684 );
685 status.add_metadata(
686 "uptime_seconds",
687 serde_json::Value::from(app_stats.uptime.as_secs()),
688 );
689 status.add_metadata(
690 "manager_count",
691 serde_json::Value::from(app_stats.manager_count),
692 );
693 status.add_metadata("version", serde_json::Value::String(app_stats.version));
694
695 status
696 }
697
698 async fn health_check(&self) -> HealthStatus {
699 let health = self.get_health().await;
700 health.status
701 }
702}
703
704struct SimplePluginLoader {
706 }
708
709impl SimplePluginLoader {
710 fn new() -> Self {
711 Self {}
712 }
713}
714
715#[async_trait]
716impl crate::plugin::PluginLoader for SimplePluginLoader {
717 async fn load_plugin(&self, _path: &str) -> Result<Box<dyn crate::plugin::Plugin>> {
718 Err(Error::plugin(
719 "loader",
720 "Plugin loading not implemented in example",
721 ))
722 }
723
724 async fn validate_plugin(
725 &self,
726 _plugin: &dyn crate::plugin::Plugin,
727 ) -> Result<crate::plugin::ValidationResult> {
728 Ok(crate::plugin::ValidationResult {
729 is_valid: true,
730 errors: Vec::new(),
731 warnings: Vec::new(),
732 })
733 }
734
735 async fn unload_plugin(&self, _plugin_id: &str) -> Result<()> {
736 Ok(())
737 }
738}
739
740#[cfg(test)]
741mod tests {
742 use super::*;
743
744 #[tokio::test]
745 async fn test_application_lifecycle() {
746 let mut app = ApplicationCore::new();
747
748 assert_eq!(app.get_state().await, ApplicationState::Created);
749
750 app.initialize().await.unwrap();
751 assert_eq!(app.get_state().await, ApplicationState::Running);
752
753 app.shutdown().await.unwrap();
754 assert_eq!(app.get_state().await, ApplicationState::Shutdown);
755 }
756
757 #[tokio::test]
758 async fn test_application_health() {
759 let mut app = ApplicationCore::new();
760 app.initialize().await.unwrap();
761
762 let health = app.get_health().await;
763 assert!(matches!(
764 health.status,
765 HealthStatus::Healthy | HealthStatus::Degraded
766 ));
767
768 app.shutdown().await.unwrap();
769 }
770
771 #[tokio::test]
772 async fn test_application_stats() {
773 let mut app = ApplicationCore::new();
774 app.initialize().await.unwrap();
775
776 let stats = app.get_stats().await;
777 assert_eq!(stats.version, crate::VERSION);
778 assert_eq!(stats.state, ApplicationState::Running);
779
780 app.shutdown().await.unwrap();
781 }
782}