1use nerve_core_errors::NerveResult;
7use nerve_core_traits::{
8 NerveComponent, NervePlugin,
9};
10use nerve_core_types::{
11 ComponentType, SystemStatistics,
12};
13use nerve_plugin_system::PluginManager;
14use std::sync::Arc;
15
16use crate::integration::plugin_adapters::{
17 CommunicationComponentAdapter, MemoryComponentAdapter, NodeComponentAdapter, ThreadComponentAdapter,
18};
19use crate::integration::plugin_traits::{
20 PluginCommunicationComponent, PluginMemoryComponent, PluginNodeComponent, PluginThreadComponent,
21};
22
23pub struct PluginNerveSystem {
28 plugin_manager: Arc<PluginManager>,
30 config: SystemConfig,
32 memory_component: Option<Arc<dyn PluginMemoryComponent>>,
34 thread_component: Option<Arc<dyn PluginThreadComponent>>,
36 node_component: Option<Arc<dyn PluginNodeComponent>>,
38 communication_component: Option<Arc<dyn PluginCommunicationComponent>>,
40}
41
42#[derive(Debug, Clone)]
44pub struct SystemConfig {
45 pub max_memory_bytes: u64,
47 pub max_threads: usize,
49 pub max_queue_size: usize,
51 pub performance_monitoring: bool,
53 pub plugin_loading_strategy: PluginLoadingStrategy,
55}
56
57#[derive(Debug, Clone)]
59pub enum PluginLoadingStrategy {
60 LoadAll,
62 LoadSpecific(Vec<ComponentType>),
64 LazyLoad,
66}
67
68impl Default for SystemConfig {
69 fn default() -> Self {
70 Self {
71 max_memory_bytes: 1_000_000_000, max_threads: 16,
73 max_queue_size: 10_000,
74 performance_monitoring: true,
75 plugin_loading_strategy: PluginLoadingStrategy::LoadAll,
76 }
77 }
78}
79
80impl PluginNerveSystem {
81 pub fn new() -> NerveResult<Self> {
83 Self::with_config(SystemConfig::default())
84 }
85
86 pub fn with_config(config: SystemConfig) -> NerveResult<Self> {
88 if config.max_memory_bytes == 0 {
90 return Err(nerve_core_errors::NerveError::Configuration(
91 "Maximum memory bytes must be greater than 0".to_string(),
92 ));
93 }
94
95 if config.max_threads == 0 {
96 return Err(nerve_core_errors::NerveError::Configuration(
97 "Maximum threads must be greater than 0".to_string(),
98 ));
99 }
100
101 if config.max_queue_size == 0 {
102 return Err(nerve_core_errors::NerveError::Configuration(
103 "Maximum queue size must be greater than 0".to_string(),
104 ));
105 }
106
107 let plugin_manager = Arc::new(PluginManager::new());
109
110 Ok(Self {
111 plugin_manager,
112 config,
113 memory_component: None,
114 thread_component: None,
115 node_component: None,
116 communication_component: None,
117 })
118 }
119
120 pub fn load_plugins(&mut self) -> NerveResult<()> {
122 println!("Loading plugins with strategy: {:?}", self.config.plugin_loading_strategy);
123
124 let strategy = self.config.plugin_loading_strategy.clone();
126
127 match strategy {
128 PluginLoadingStrategy::LoadAll => {
129 self.load_memory_plugin()?;
130 self.load_thread_plugin()?;
131 self.load_node_plugin()?;
132 self.load_communication_plugin()?;
133 }
134 PluginLoadingStrategy::LoadSpecific(types) => {
135 for component_type in types {
136 match component_type {
137 ComponentType::Memory => self.load_memory_plugin()?,
138 ComponentType::Thread => self.load_thread_plugin()?,
139 ComponentType::Node => self.load_node_plugin()?,
140 ComponentType::Communication => self.load_communication_plugin()?,
141 ComponentType::QoS | ComponentType::Integration => {
142 println!("⚠️ Component type {:?} not yet supported in plugin system", component_type);
144 }
145 }
146 }
147 }
148 PluginLoadingStrategy::LazyLoad => {
149 println!("Lazy loading enabled - plugins will be loaded on demand");
151 }
152 }
153
154 println!("Plugin loading completed successfully");
155 Ok(())
156 }
157
158 fn load_memory_plugin(&mut self) -> NerveResult<()> {
160 use nerve_memory::{MemoryManager, MemoryPlugin};
161
162 let plugin = Arc::new(MemoryPlugin::new(self.config.max_memory_bytes));
164 self.plugin_manager.load_plugin(plugin.clone())?;
165
166 let memory_manager = Arc::new(MemoryManager::new(self.config.max_memory_bytes));
168 let adapter = Arc::new(MemoryComponentAdapter::new(memory_manager));
169
170 self.memory_component = Some(adapter);
172
173 println!("✅ Memory plugin loaded successfully");
174 Ok(())
175 }
176
177 fn load_thread_plugin(&mut self) -> NerveResult<()> {
179 use nerve_thread::{ThreadManager, ThreadPlugin};
180
181 let plugin = Arc::new(ThreadPlugin::new(self.config.max_threads));
183 self.plugin_manager.load_plugin(plugin.clone())?;
184
185 let thread_manager = Arc::new(ThreadManager::new(self.config.max_threads));
187 let adapter = Arc::new(ThreadComponentAdapter::new(thread_manager));
188
189 self.thread_component = Some(adapter);
191
192 println!("✅ Thread plugin loaded successfully");
193 Ok(())
194 }
195
196 fn load_node_plugin(&mut self) -> NerveResult<()> {
198 use nerve_node::{NodeManager, NodePlugin};
199
200 let plugin = Arc::new(NodePlugin::new());
202 self.plugin_manager.load_plugin(plugin.clone())?;
203
204 let node_manager = Arc::new(NodeManager::new());
206 let adapter = Arc::new(NodeComponentAdapter::new(node_manager));
207
208 self.node_component = Some(adapter);
210
211 println!("✅ Node plugin loaded successfully");
212 Ok(())
213 }
214
215 fn load_communication_plugin(&mut self) -> NerveResult<()> {
217 use nerve_communication::{CommunicationManager, CommunicationPlugin};
218
219 let plugin = Arc::new(CommunicationPlugin::new());
221 self.plugin_manager.load_plugin(plugin.clone())?;
222
223 let communication_manager = Arc::new(CommunicationManager::new());
225 let adapter = Arc::new(CommunicationComponentAdapter::new(communication_manager));
226
227 self.communication_component = Some(adapter);
229
230 println!("✅ Communication plugin loaded successfully");
231 Ok(())
232 }
233
234 pub fn memory_component(&mut self) -> NerveResult<&Arc<dyn PluginMemoryComponent>> {
236 if self.memory_component.is_none() {
237 self.load_memory_plugin()?;
238 }
239 self.memory_component
240 .as_ref()
241 .ok_or_else(|| nerve_core_errors::NerveError::Component {
242 component_type: nerve_core_types::ComponentType::Memory,
243 message: "Memory component not available".to_string(),
244 })
245 }
246
247 pub fn thread_component(&mut self) -> NerveResult<&Arc<dyn PluginThreadComponent>> {
249 if self.thread_component.is_none() {
250 self.load_thread_plugin()?;
251 }
252 self.thread_component
253 .as_ref()
254 .ok_or_else(|| nerve_core_errors::NerveError::Component {
255 component_type: nerve_core_types::ComponentType::Thread,
256 message: "Thread component not available".to_string(),
257 })
258 }
259
260 pub fn node_component(&mut self) -> NerveResult<&Arc<dyn PluginNodeComponent>> {
262 if self.node_component.is_none() {
263 self.load_node_plugin()?;
264 }
265 self.node_component
266 .as_ref()
267 .ok_or_else(|| nerve_core_errors::NerveError::Component {
268 component_type: nerve_core_types::ComponentType::Node,
269 message: "Node component not available".to_string(),
270 })
271 }
272
273 pub fn communication_component(&mut self) -> NerveResult<&Arc<dyn PluginCommunicationComponent>> {
275 if self.communication_component.is_none() {
276 self.load_communication_plugin()?;
277 }
278 self.communication_component
279 .as_ref()
280 .ok_or_else(|| nerve_core_errors::NerveError::Component {
281 component_type: nerve_core_types::ComponentType::Communication,
282 message: "Communication component not available".to_string(),
283 })
284 }
285
286 pub fn plugin_manager(&self) -> &Arc<PluginManager> {
288 &self.plugin_manager
289 }
290
291 pub fn config(&self) -> &SystemConfig {
293 &self.config
294 }
295
296 pub fn is_healthy(&self) -> bool {
298 self.plugin_manager.system_health()
299 }
300
301 pub fn health_status(&self) -> String {
303 if self.is_healthy() {
304 "Healthy".to_string()
305 } else {
306 "Unhealthy".to_string()
307 }
308 }
309
310 pub fn get_statistics(&self) -> SystemStatistics {
312 let mut combined_stats = SystemStatistics::default();
313
314 for plugin in self.plugin_manager.get_all_plugins() {
316 let plugin_stats = plugin.get_statistics();
317 combined_stats.messages_processed += plugin_stats.messages_processed;
318 combined_stats.errors_encountered += plugin_stats.errors_encountered;
319 }
321
322 combined_stats
323 }
324
325 pub fn loaded_plugin_types(&self) -> Vec<ComponentType> {
327 self.plugin_manager.get_loaded_plugin_types()
328 }
329
330 pub fn plugin_count(&self) -> usize {
332 self.plugin_manager.get_all_plugins().len()
333 }
334
335 pub fn process_message(&mut self, topic: &str, payload: Vec<u8>) -> NerveResult<()> {
337 println!("Processing message via plugin system...");
338
339 let memory_component = self.memory_component()?;
341 println!(" Memory component: {} (healthy: {})",
342 memory_component.id().name,
343 memory_component.is_healthy()
344 );
345
346 let communication_component = self.communication_component()?;
348 println!(" Communication component: {} (healthy: {})",
349 communication_component.id().name,
350 communication_component.is_healthy()
351 );
352
353 let thread_component = self.thread_component()?;
355 println!(" Thread component: {} (healthy: {})",
356 thread_component.id().name,
357 thread_component.is_healthy()
358 );
359
360 let node_component = self.node_component()?;
362 println!(" Node component: {} (healthy: {})",
363 node_component.id().name,
364 node_component.is_healthy()
365 );
366
367 println!(" Message processed successfully via plugin system");
368 println!(" Topic: {}, Payload size: {} bytes", topic, payload.len());
369
370 Ok(())
371 }
372
373 pub fn shutdown(self) -> NerveResult<()> {
375 println!("🔄 Starting plugin-based system shutdown...");
376
377 println!("✅ Plugin-based system shutdown complete");
379
380 Ok(())
381 }
382}
383
384impl Default for PluginNerveSystem {
385 fn default() -> Self {
386 Self::new().expect("Failed to create default PluginNerveSystem")
387 }
388}
389
390#[cfg(test)]
391mod tests {
392 use super::*;
393
394 #[test]
395 fn test_plugin_nerve_system_creation() {
396 let system = PluginNerveSystem::new();
397 assert!(system.is_ok());
398
399 let mut system = system.unwrap();
400 assert!(system.is_healthy());
401 }
402
403 #[test]
404 fn test_plugin_nerve_system_with_config() {
405 let config = SystemConfig {
406 max_memory_bytes: 500_000_000,
407 max_threads: 8,
408 max_queue_size: 5_000,
409 performance_monitoring: true,
410 plugin_loading_strategy: PluginLoadingStrategy::LoadAll,
411 };
412
413 let system = PluginNerveSystem::with_config(config);
414 assert!(system.is_ok());
415
416 let system = system.unwrap();
417 assert_eq!(system.config().max_memory_bytes, 500_000_000);
418 assert_eq!(system.config().max_threads, 8);
419 assert_eq!(system.config().max_queue_size, 5_000);
420 }
421
422 #[test]
423 fn test_plugin_nerve_system_invalid_config() {
424 let config = SystemConfig {
425 max_memory_bytes: 0, max_threads: 8,
427 max_queue_size: 5_000,
428 performance_monitoring: true,
429 plugin_loading_strategy: PluginLoadingStrategy::LoadAll,
430 };
431
432 let system = PluginNerveSystem::with_config(config);
433 assert!(system.is_err());
434 }
435
436 #[test]
437 fn test_plugin_loading() {
438 let mut system = PluginNerveSystem::new().unwrap();
439
440 assert_eq!(system.plugin_count(), 0);
442
443 let result = system.load_plugins();
445 assert!(result.is_ok());
446
447 assert_eq!(system.plugin_count(), 4);
449 assert!(system.is_healthy());
450 }
451
452 #[test]
453 fn test_system_statistics() {
454 let system = PluginNerveSystem::new().unwrap();
455 let stats = system.get_statistics();
456
457 assert_eq!(stats.messages_processed, 0);
459 assert_eq!(stats.errors_encountered, 0);
460 }
461
462 #[test]
463 fn test_health_status() {
464 let system = PluginNerveSystem::new().unwrap();
465 let status = system.health_status();
466
467 assert_eq!(status, "Healthy");
469 }
470}