qorzen_oxide/
manager.rs

1// src/manager.rs - Enhanced manager system with plugin support
2
3use std::collections::HashMap;
4use std::fmt;
5use std::sync::Arc;
6use std::time::Duration;
7
8use crate::utils::Time;
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11use tokio::sync::RwLock;
12use uuid::Uuid;
13
14use crate::error::{Error, ManagerOperation, Result};
15use crate::types::Metadata;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
18pub enum ManagerState {
19    Created,
20    Initializing,
21    Running,
22    Paused,
23    ShuttingDown,
24    Shutdown,
25    Error,
26    Maintenance,
27}
28
29impl fmt::Display for ManagerState {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            Self::Created => write!(f, "CREATED"),
33            Self::Initializing => write!(f, "INITIALIZING"),
34            Self::Running => write!(f, "RUNNING"),
35            Self::Paused => write!(f, "PAUSED"),
36            Self::ShuttingDown => write!(f, "SHUTTING_DOWN"),
37            Self::Shutdown => write!(f, "SHUTDOWN"),
38            Self::Error => write!(f, "ERROR"),
39            Self::Maintenance => write!(f, "MAINTENANCE"),
40        }
41    }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
45pub enum HealthStatus {
46    Healthy,
47    Degraded,
48    Unhealthy,
49    Unknown,
50}
51
52impl fmt::Display for HealthStatus {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            Self::Healthy => write!(f, "HEALTHY"),
56            Self::Degraded => write!(f, "DEGRADED"),
57            Self::Unhealthy => write!(f, "UNHEALTHY"),
58            Self::Unknown => write!(f, "UNKNOWN"),
59        }
60    }
61}
62
63#[derive(Debug, Clone, Default, Serialize, Deserialize)]
64pub struct PlatformRequirements {
65    pub requires_filesystem: bool,
66    pub requires_network: bool,
67    pub requires_database: bool,
68    pub requires_native_apis: bool,
69    pub minimum_permissions: Vec<String>,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct ManagerStatus {
74    pub id: Uuid,
75    pub name: String,
76    pub state: ManagerState,
77    pub health: HealthStatus,
78    pub created_at: DateTime<Utc>,
79    pub started_at: Option<DateTime<Utc>>,
80    pub uptime: Option<Duration>,
81    pub last_updated: DateTime<Utc>,
82    pub message: Option<String>,
83    pub metadata: Metadata,
84    pub metrics: ManagerMetrics,
85}
86
87impl ManagerStatus {
88    /// Creates a new manager status
89    pub fn new(id: Uuid, name: impl Into<String>, state: ManagerState) -> Self {
90        Self {
91            id,
92            name: name.into(),
93            state,
94            health: HealthStatus::Unknown,
95            created_at: Time::now(),
96            started_at: None,
97            uptime: None,
98            last_updated: Time::now(),
99            message: None,
100            metadata: HashMap::new(),
101            metrics: ManagerMetrics::default(),
102        }
103    }
104
105    /// Updates the manager state
106    pub fn update_state(&mut self, state: ManagerState) {
107        self.state = state;
108        self.last_updated = Time::now();
109
110        if state == ManagerState::Running && self.started_at.is_none() {
111            self.started_at = Some(Time::now());
112        }
113
114        if let Some(started) = self.started_at {
115            if matches!(state, ManagerState::Running | ManagerState::Paused) {
116                self.uptime = Time::now().signed_duration_since(started).to_std().ok();
117            }
118        }
119    }
120
121    /// Sets the health status
122    pub fn set_health(&mut self, health: HealthStatus) {
123        self.health = health;
124        self.last_updated = Time::now();
125    }
126
127    /// Sets a status message
128    pub fn set_message(&mut self, message: impl Into<String>) {
129        self.message = Some(message.into());
130        self.last_updated = Time::now();
131    }
132
133    /// Adds metadata to the status
134    pub fn add_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
135        self.metadata.insert(key.into(), value);
136        self.last_updated = Time::now();
137    }
138
139    /// Updates the metrics
140    pub fn update_metrics(&mut self, metrics: ManagerMetrics) {
141        self.metrics = metrics;
142        self.last_updated = Time::now();
143    }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct ManagerMetrics {
148    pub cpu_usage_percent: f64,
149    pub memory_usage_bytes: u64,
150    pub active_operations: u32,
151    pub total_operations: u64,
152    pub operations_per_second: f64,
153    pub avg_latency_ms: f64,
154    pub error_rate: f64,
155    pub custom_metrics: HashMap<String, f64>,
156}
157
158impl Default for ManagerMetrics {
159    fn default() -> Self {
160        Self {
161            cpu_usage_percent: 0.0,
162            memory_usage_bytes: 0,
163            active_operations: 0,
164            total_operations: 0,
165            operations_per_second: 0.0,
166            avg_latency_ms: 0.0,
167            error_rate: 0.0,
168            custom_metrics: HashMap::new(),
169        }
170    }
171}
172
173// Platform-specific trait bounds
174#[cfg(not(target_arch = "wasm32"))]
175pub trait PlatformSync: Send + Sync {}
176#[cfg(not(target_arch = "wasm32"))]
177impl<T: Send + Sync> PlatformSync for T {}
178
179#[cfg(target_arch = "wasm32")]
180pub trait PlatformSync {}
181#[cfg(target_arch = "wasm32")]
182impl<T> PlatformSync for T {}
183
184/// Core trait for all system managers - conditional Send requirement based on target
185#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
186#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
187pub trait Manager: PlatformSync + fmt::Debug {
188    /// Returns the manager name
189    fn name(&self) -> &str;
190
191    /// Returns the manager ID
192    fn id(&self) -> Uuid;
193
194    /// Initializes the manager
195    async fn initialize(&mut self) -> Result<()>;
196
197    /// Shuts down the manager
198    async fn shutdown(&mut self) -> Result<()>;
199
200    /// Returns current status
201    async fn status(&self) -> ManagerStatus;
202
203    /// Performs health check
204    async fn health_check(&self) -> HealthStatus {
205        let status = self.status().await;
206        match status.state {
207            ManagerState::Running => HealthStatus::Healthy,
208            ManagerState::Paused | ManagerState::Maintenance => HealthStatus::Degraded,
209            ManagerState::Error => HealthStatus::Unhealthy,
210            _ => HealthStatus::Unknown,
211        }
212    }
213
214    /// Pauses the manager
215    async fn pause(&mut self) -> Result<()> {
216        Err(Error::manager(
217            self.name(),
218            ManagerOperation::Pause,
219            "Pause operation not supported",
220        ))
221    }
222
223    /// Resumes the manager
224    async fn resume(&mut self) -> Result<()> {
225        Err(Error::manager(
226            self.name(),
227            ManagerOperation::Resume,
228            "Resume operation not supported",
229        ))
230    }
231
232    /// Restarts the manager
233    async fn restart(&mut self) -> Result<()> {
234        self.shutdown().await?;
235        self.initialize().await
236    }
237
238    /// Gets current configuration
239    async fn get_config(&self) -> Option<serde_json::Value> {
240        None
241    }
242
243    /// Updates configuration
244    async fn update_config(&mut self, _config: serde_json::Value) -> Result<()> {
245        Err(Error::manager(
246            self.name(),
247            ManagerOperation::Configure,
248            "Configuration update not supported",
249        ))
250    }
251
252    /// Returns dependencies
253    fn dependencies(&self) -> Vec<String> {
254        Vec::new()
255    }
256
257    /// Returns initialization priority
258    fn priority(&self) -> i32 {
259        0
260    }
261
262    /// Checks if manager is essential for system operation
263    fn is_essential(&self) -> bool {
264        false
265    }
266
267    /// Returns manager version
268    fn version(&self) -> Option<String> {
269        None
270    }
271
272    /// Returns manager description
273    fn description(&self) -> Option<String> {
274        None
275    }
276
277    /// Checks if manager supports runtime reloading
278    fn supports_runtime_reload(&self) -> bool {
279        false
280    }
281
282    /// Reloads configuration at runtime
283    async fn reload_config(&mut self, _config: serde_json::Value) -> Result<()> {
284        Err(Error::manager(
285            self.name(),
286            ManagerOperation::Reload,
287            "Runtime configuration reload not supported",
288        ))
289    }
290
291    /// Returns required permissions
292    fn required_permissions(&self) -> Vec<String> {
293        Vec::new()
294    }
295
296    /// Returns platform requirements
297    fn platform_requirements(&self) -> PlatformRequirements {
298        PlatformRequirements::default()
299    }
300}
301
302/// Managed state container for managers
303pub struct ManagedState {
304    id: Uuid,
305    name: String,
306    status: Arc<RwLock<ManagerStatus>>,
307}
308
309impl ManagedState {
310    /// Creates a new managed state
311    pub fn new(id: Uuid, name: impl Into<String>) -> Self {
312        let name_str = name.into();
313        let status = ManagerStatus::new(id, name_str.clone(), ManagerState::Created);
314
315        Self {
316            id,
317            name: name_str,
318            status: Arc::new(RwLock::new(status)),
319        }
320    }
321
322    /// Returns the manager ID
323    pub fn id(&self) -> Uuid {
324        self.id
325    }
326
327    /// Returns the manager name
328    pub fn name(&self) -> &str {
329        &self.name
330    }
331
332    /// Sets the manager state
333    pub async fn set_state(&self, state: ManagerState) {
334        let mut status = self.status.write().await;
335        status.update_state(state);
336    }
337
338    /// Sets the health status
339    pub async fn set_health(&self, health: HealthStatus) {
340        let mut status = self.status.write().await;
341        status.set_health(health);
342    }
343
344    /// Sets a status message
345    pub async fn set_message(&self, message: impl Into<String>) {
346        let mut status = self.status.write().await;
347        status.set_message(message);
348    }
349
350    /// Adds metadata
351    pub async fn add_metadata(&self, key: impl Into<String>, value: serde_json::Value) {
352        let mut status = self.status.write().await;
353        status.add_metadata(key, value);
354    }
355
356    /// Updates metrics
357    pub async fn update_metrics(&self, metrics: ManagerMetrics) {
358        let mut status = self.status.write().await;
359        status.update_metrics(metrics);
360    }
361
362    /// Returns current status
363    pub async fn status(&self) -> ManagerStatus {
364        self.status.read().await.clone()
365    }
366
367    /// Returns current state
368    pub async fn state(&self) -> ManagerState {
369        self.status.read().await.state
370    }
371
372    /// Returns current health
373    pub async fn health(&self) -> HealthStatus {
374        self.status.read().await.health
375    }
376}
377
378impl fmt::Debug for ManagedState {
379    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380        f.debug_struct("ManagedState")
381            .field("id", &self.id)
382            .field("name", &self.name)
383            .finish()
384    }
385}
386
387#[cfg(test)]
388mod tests {
389    use super::*;
390
391    #[derive(Debug)]
392    struct TestManager {
393        state: ManagedState,
394    }
395
396    impl TestManager {
397        fn new(name: &str) -> Self {
398            Self {
399                state: ManagedState::new(Uuid::new_v4(), name),
400            }
401        }
402
403        async fn current_state(&self) -> ManagerState {
404            self.state.state().await
405        }
406    }
407
408    #[test]
409    fn test_manager_status_creation() {
410        let manager = TestManager::new("test_manager");
411        assert_eq!(manager.state.name(), "test_manager");
412    }
413
414    #[tokio::test]
415    async fn test_managed_state_operations() {
416        let state = ManagedState::new(Uuid::new_v4(), "test");
417
418        assert_eq!(state.state().await, ManagerState::Created);
419
420        state.set_state(ManagerState::Running).await;
421        assert_eq!(state.state().await, ManagerState::Running);
422
423        state.set_health(HealthStatus::Healthy).await;
424        assert_eq!(state.health().await, HealthStatus::Healthy);
425
426        state.set_message("Test message").await;
427        let status = state.status().await;
428        assert_eq!(status.message, Some("Test message".to_string()));
429    }
430}