1use 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 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 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 pub fn set_health(&mut self, health: HealthStatus) {
123 self.health = health;
124 self.last_updated = Time::now();
125 }
126
127 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 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 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#[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#[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 fn name(&self) -> &str;
190
191 fn id(&self) -> Uuid;
193
194 async fn initialize(&mut self) -> Result<()>;
196
197 async fn shutdown(&mut self) -> Result<()>;
199
200 async fn status(&self) -> ManagerStatus;
202
203 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 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 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 async fn restart(&mut self) -> Result<()> {
234 self.shutdown().await?;
235 self.initialize().await
236 }
237
238 async fn get_config(&self) -> Option<serde_json::Value> {
240 None
241 }
242
243 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 fn dependencies(&self) -> Vec<String> {
254 Vec::new()
255 }
256
257 fn priority(&self) -> i32 {
259 0
260 }
261
262 fn is_essential(&self) -> bool {
264 false
265 }
266
267 fn version(&self) -> Option<String> {
269 None
270 }
271
272 fn description(&self) -> Option<String> {
274 None
275 }
276
277 fn supports_runtime_reload(&self) -> bool {
279 false
280 }
281
282 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 fn required_permissions(&self) -> Vec<String> {
293 Vec::new()
294 }
295
296 fn platform_requirements(&self) -> PlatformRequirements {
298 PlatformRequirements::default()
299 }
300}
301
302pub struct ManagedState {
304 id: Uuid,
305 name: String,
306 status: Arc<RwLock<ManagerStatus>>,
307}
308
309impl ManagedState {
310 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 pub fn id(&self) -> Uuid {
324 self.id
325 }
326
327 pub fn name(&self) -> &str {
329 &self.name
330 }
331
332 pub async fn set_state(&self, state: ManagerState) {
334 let mut status = self.status.write().await;
335 status.update_state(state);
336 }
337
338 pub async fn set_health(&self, health: HealthStatus) {
340 let mut status = self.status.write().await;
341 status.set_health(health);
342 }
343
344 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 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 pub async fn update_metrics(&self, metrics: ManagerMetrics) {
358 let mut status = self.status.write().await;
359 status.update_metrics(metrics);
360 }
361
362 pub async fn status(&self) -> ManagerStatus {
364 self.status.read().await.clone()
365 }
366
367 pub async fn state(&self) -> ManagerState {
369 self.status.read().await.state
370 }
371
372 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}