sklears_compose/modular_framework/
component_framework.rs

1//! Core Component Framework
2//!
3//! This module provides the fundamental abstractions for modular components including
4//! component traits, factory patterns, configuration management, and component validation
5//! for building pluggable and composable system architectures.
6
7use serde::{Deserialize, Serialize};
8use sklears_core::error::{Result as SklResult, SklearsError};
9use std::any::Any;
10use std::collections::HashMap;
11use std::sync::Arc;
12use thiserror::Error;
13
14/// Core component trait defining the interface for all modular components
15///
16/// Provides standard lifecycle methods, configuration handling, and capability
17/// introspection for components within the modular framework.
18pub trait PluggableComponent: Send + Sync + Any {
19    /// Initialize the component with configuration
20    fn initialize(&mut self, config: &ComponentConfig) -> SklResult<()>;
21
22    /// Start the component (transition to active state)
23    fn start(&mut self) -> SklResult<()>;
24
25    /// Stop the component (graceful shutdown)
26    fn stop(&mut self) -> SklResult<()>;
27
28    /// Pause the component (temporary suspension)
29    fn pause(&mut self) -> SklResult<()>;
30
31    /// Resume the component from paused state
32    fn resume(&mut self) -> SklResult<()>;
33
34    /// Get component identifier
35    fn component_id(&self) -> &str;
36
37    /// Get component type name
38    fn component_type(&self) -> &str;
39
40    /// Get component version
41    fn version(&self) -> &str;
42
43    /// Get current component state
44    fn current_state(&self) -> ComponentState;
45
46    /// Check if component is healthy
47    fn health_check(&self) -> SklResult<HealthStatus>;
48
49    /// Get component capabilities
50    fn capabilities(&self) -> Vec<ComponentCapability>;
51
52    /// Get component dependencies
53    fn dependencies(&self) -> Vec<ComponentDependency>;
54
55    /// Validate component configuration
56    fn validate_config(&self, config: &ComponentConfig) -> SklResult<()>;
57
58    /// Get component metrics
59    fn get_metrics(&self) -> ComponentMetrics;
60
61    /// Handle component events
62    fn handle_event(&mut self, event: &ComponentEvent) -> SklResult<()>;
63
64    /// Clone the component (for factory pattern)
65    fn clone_component(&self) -> Box<dyn PluggableComponent>;
66
67    /// Downcast to concrete type
68    fn as_any(&self) -> &dyn Any;
69
70    /// Mutable downcast to concrete type
71    fn as_any_mut(&mut self) -> &mut dyn Any;
72}
73
74/// Component states in the lifecycle
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
76pub enum ComponentState {
77    /// Component is created but not initialized
78    Created,
79    /// Component is being initialized
80    Initializing,
81    /// Component is initialized but not started
82    Ready,
83    /// Component is running
84    Running,
85    /// Component is paused
86    Paused,
87    /// Component is stopping
88    Stopping,
89    /// Component is stopped
90    Stopped,
91    /// Component is in error state
92    Error(String),
93}
94
95/// Component health status
96#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
97pub enum HealthStatus {
98    /// Component is healthy
99    Healthy,
100    /// Component has warnings but is functional
101    Warning(String),
102    /// Component has degraded performance
103    Degraded(String),
104    /// Component is unhealthy
105    Unhealthy(String),
106    /// Component is unresponsive
107    Unresponsive,
108}
109
110/// Component capability descriptor
111#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
112pub struct ComponentCapability {
113    /// Capability name
114    pub name: String,
115    /// Capability description
116    pub description: String,
117    /// Required configuration parameters
118    pub required_config: Vec<String>,
119    /// Optional configuration parameters
120    pub optional_config: Vec<String>,
121    /// Capability version
122    pub version: String,
123}
124
125/// Component dependency descriptor
126#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
127pub struct ComponentDependency {
128    /// Dependency component type
129    pub component_type: String,
130    /// Required version range
131    pub version_requirement: String,
132    /// Whether dependency is optional
133    pub optional: bool,
134    /// Required capabilities from dependency
135    pub required_capabilities: Vec<String>,
136}
137
138/// Component configuration
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct ComponentConfig {
141    /// Component identifier
142    pub component_id: String,
143    /// Component type
144    pub component_type: String,
145    /// Configuration parameters
146    pub parameters: HashMap<String, ConfigValue>,
147    /// Environment-specific settings
148    pub environment: HashMap<String, String>,
149    /// Resource constraints
150    pub resources: ResourceConstraints,
151    /// Feature flags
152    pub features: HashMap<String, bool>,
153}
154
155impl ComponentConfig {
156    /// Create a new component configuration
157    #[must_use]
158    pub fn new(component_id: &str, component_type: &str) -> Self {
159        Self {
160            component_id: component_id.to_string(),
161            component_type: component_type.to_string(),
162            parameters: HashMap::new(),
163            environment: HashMap::new(),
164            resources: ResourceConstraints::default(),
165            features: HashMap::new(),
166        }
167    }
168
169    /// Add a configuration parameter
170    #[must_use]
171    pub fn with_parameter(mut self, key: &str, value: ConfigValue) -> Self {
172        self.parameters.insert(key.to_string(), value);
173        self
174    }
175
176    /// Add an environment variable
177    #[must_use]
178    pub fn with_environment(mut self, key: &str, value: &str) -> Self {
179        self.environment.insert(key.to_string(), value.to_string());
180        self
181    }
182
183    /// Set resource constraints
184    #[must_use]
185    pub fn with_resources(mut self, resources: ResourceConstraints) -> Self {
186        self.resources = resources;
187        self
188    }
189
190    /// Add a feature flag
191    #[must_use]
192    pub fn with_feature(mut self, feature: &str, enabled: bool) -> Self {
193        self.features.insert(feature.to_string(), enabled);
194        self
195    }
196
197    /// Get parameter value
198    #[must_use]
199    pub fn get_parameter(&self, key: &str) -> Option<&ConfigValue> {
200        self.parameters.get(key)
201    }
202
203    /// Get environment variable
204    pub fn get_environment(&self, key: &str) -> Option<&str> {
205        self.environment.get(key).map(String::as_str)
206    }
207
208    /// Check if feature is enabled
209    #[must_use]
210    pub fn is_feature_enabled(&self, feature: &str) -> bool {
211        self.features.get(feature).copied().unwrap_or(false)
212    }
213}
214
215/// Configuration value types
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub enum ConfigValue {
218    /// String
219    String(String),
220    /// Integer
221    Integer(i64),
222    /// Float
223    Float(f64),
224    /// Boolean
225    Boolean(bool),
226    /// Array
227    Array(Vec<ConfigValue>),
228    /// Object
229    Object(HashMap<String, ConfigValue>),
230}
231
232/// Resource constraints for components
233#[derive(Debug, Clone, Serialize, Deserialize, Default)]
234pub struct ResourceConstraints {
235    /// Maximum memory usage in bytes
236    pub max_memory: Option<u64>,
237    /// Maximum CPU usage percentage
238    pub max_cpu: Option<f64>,
239    /// Maximum number of threads
240    pub max_threads: Option<u32>,
241    /// Maximum disk usage in bytes
242    pub max_disk: Option<u64>,
243    /// Network bandwidth limit in bytes per second
244    pub max_bandwidth: Option<u64>,
245}
246
247/// Component metrics for monitoring
248#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct ComponentMetrics {
250    /// Component uptime
251    pub uptime: std::time::Duration,
252    /// Memory usage in bytes
253    pub memory_usage: u64,
254    /// CPU usage percentage
255    pub cpu_usage: f64,
256    /// Number of processed requests
257    pub processed_requests: u64,
258    /// Number of failed requests
259    pub failed_requests: u64,
260    /// Average processing time
261    pub average_processing_time: std::time::Duration,
262    /// Custom metrics
263    pub custom_metrics: HashMap<String, MetricValue>,
264}
265
266impl ComponentMetrics {
267    #[must_use]
268    pub fn new() -> Self {
269        Self {
270            uptime: std::time::Duration::from_secs(0),
271            memory_usage: 0,
272            cpu_usage: 0.0,
273            processed_requests: 0,
274            failed_requests: 0,
275            average_processing_time: std::time::Duration::from_secs(0),
276            custom_metrics: HashMap::new(),
277        }
278    }
279
280    /// Add a custom metric
281    pub fn add_custom_metric(&mut self, name: &str, value: MetricValue) {
282        self.custom_metrics.insert(name.to_string(), value);
283    }
284
285    /// Get success rate
286    #[must_use]
287    pub fn success_rate(&self) -> f64 {
288        if self.processed_requests == 0 {
289            1.0
290        } else {
291            (self.processed_requests - self.failed_requests) as f64 / self.processed_requests as f64
292        }
293    }
294}
295
296/// Metric value types
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub enum MetricValue {
299    /// Counter
300    Counter(u64),
301    /// Gauge
302    Gauge(f64),
303    /// Histogram
304    Histogram(Vec<f64>),
305    /// Timer
306    Timer(std::time::Duration),
307}
308
309/// Component event for inter-component communication
310#[derive(Debug, Clone, Serialize, Deserialize)]
311pub struct ComponentEvent {
312    /// Event identifier
313    pub event_id: String,
314    /// Source component
315    pub source: String,
316    /// Event type
317    pub event_type: String,
318    /// Event data
319    pub data: HashMap<String, String>,
320    /// Event timestamp
321    pub timestamp: std::time::SystemTime,
322}
323
324/// Component factory trait for creating components
325pub trait ComponentFactory: Send + Sync {
326    /// Create a new component instance
327    fn create_component(&self, config: &ComponentConfig) -> SklResult<Box<dyn PluggableComponent>>;
328
329    /// Get supported component types
330    fn supported_types(&self) -> Vec<String>;
331
332    /// Validate component configuration
333    fn validate_config(&self, config: &ComponentConfig) -> SklResult<()>;
334
335    /// Get factory metadata
336    fn factory_metadata(&self) -> FactoryMetadata;
337}
338
339/// Factory metadata
340#[derive(Debug, Clone, Serialize, Deserialize)]
341pub struct FactoryMetadata {
342    /// Factory name
343    pub name: String,
344    /// Factory version
345    pub version: String,
346    /// Supported component types
347    pub supported_types: Vec<String>,
348    /// Factory description
349    pub description: String,
350}
351
352/// Component registry for managing component types and factories
353pub struct ComponentRegistry {
354    /// Registered factories by component type
355    factories: HashMap<String, Arc<dyn ComponentFactory>>,
356    /// Component type metadata
357    type_metadata: HashMap<String, ComponentTypeMetadata>,
358    /// Registry configuration
359    config: RegistryConfig,
360}
361
362impl ComponentRegistry {
363    /// Create a new component registry
364    #[must_use]
365    pub fn new() -> Self {
366        Self {
367            factories: HashMap::new(),
368            type_metadata: HashMap::new(),
369            config: RegistryConfig::default(),
370        }
371    }
372
373    /// Register a component factory
374    pub fn register_factory(
375        &mut self,
376        component_type: &str,
377        factory: Arc<dyn ComponentFactory>,
378    ) -> SklResult<()> {
379        if self.factories.contains_key(component_type) && !self.config.allow_overrides {
380            return Err(SklearsError::InvalidInput(format!(
381                "Component type {component_type} already registered"
382            )));
383        }
384
385        self.factories
386            .insert(component_type.to_string(), factory.clone());
387
388        let metadata = ComponentTypeMetadata {
389            component_type: component_type.to_string(),
390            factory_metadata: factory.factory_metadata(),
391            registration_time: std::time::SystemTime::now(),
392        };
393
394        self.type_metadata
395            .insert(component_type.to_string(), metadata);
396        Ok(())
397    }
398
399    /// Create a component instance
400    pub fn create_component(
401        &self,
402        component_type: &str,
403        config: &ComponentConfig,
404    ) -> SklResult<Box<dyn PluggableComponent>> {
405        let factory = self.factories.get(component_type).ok_or_else(|| {
406            SklearsError::InvalidInput(format!("Component type {component_type} not registered"))
407        })?;
408
409        factory.create_component(config)
410    }
411
412    /// Get registered component types
413    #[must_use]
414    pub fn get_registered_types(&self) -> Vec<String> {
415        self.factories.keys().cloned().collect()
416    }
417
418    /// Check if component type is registered
419    #[must_use]
420    pub fn is_registered(&self, component_type: &str) -> bool {
421        self.factories.contains_key(component_type)
422    }
423
424    /// Get component type metadata
425    #[must_use]
426    pub fn get_type_metadata(&self, component_type: &str) -> Option<&ComponentTypeMetadata> {
427        self.type_metadata.get(component_type)
428    }
429
430    /// Unregister a component type
431    pub fn unregister(&mut self, component_type: &str) -> SklResult<()> {
432        self.factories.remove(component_type);
433        self.type_metadata.remove(component_type);
434        Ok(())
435    }
436}
437
438impl std::fmt::Debug for ComponentRegistry {
439    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
440        f.debug_struct("ComponentRegistry")
441            .field(
442                "factories",
443                &format!("<{} factories>", self.factories.len()),
444            )
445            .field("type_metadata", &self.type_metadata)
446            .field("config", &self.config)
447            .finish()
448    }
449}
450
451/// Component type metadata
452#[derive(Debug, Clone)]
453pub struct ComponentTypeMetadata {
454    /// Component type name
455    pub component_type: String,
456    /// Factory metadata
457    pub factory_metadata: FactoryMetadata,
458    /// Registration timestamp
459    pub registration_time: std::time::SystemTime,
460}
461
462/// Registry configuration
463#[derive(Debug, Clone)]
464pub struct RegistryConfig {
465    /// Allow factory overrides
466    pub allow_overrides: bool,
467    /// Enable type validation
468    pub enable_type_validation: bool,
469    /// Maximum registered types
470    pub max_registered_types: Option<usize>,
471}
472
473impl Default for RegistryConfig {
474    fn default() -> Self {
475        Self {
476            allow_overrides: false,
477            enable_type_validation: true,
478            max_registered_types: None,
479        }
480    }
481}
482
483/// Component framework errors
484#[derive(Debug, Error)]
485pub enum ComponentError {
486    #[error("Component initialization failed: {0}")]
487    InitializationFailed(String),
488
489    #[error("Component state transition invalid: {from} -> {to}")]
490    InvalidStateTransition { from: String, to: String },
491
492    #[error("Component configuration invalid: {0}")]
493    InvalidConfiguration(String),
494
495    #[error("Component dependency not satisfied: {0}")]
496    DependencyNotSatisfied(String),
497
498    #[error("Component health check failed: {0}")]
499    HealthCheckFailed(String),
500
501    #[error("Component capability not supported: {0}")]
502    CapabilityNotSupported(String),
503}
504
505impl Default for ComponentRegistry {
506    fn default() -> Self {
507        Self::new()
508    }
509}
510
511impl Default for ComponentMetrics {
512    fn default() -> Self {
513        Self::new()
514    }
515}
516
517// ========== Missing Types for Modular Framework ==========
518
519/// Component information details
520#[derive(Debug, Clone, Serialize, Deserialize)]
521pub struct ComponentInfo {
522    /// Component identifier
523    pub id: String,
524    /// Component type
525    pub component_type: String,
526    /// Component version
527    pub version: String,
528    /// Component description
529    pub description: Option<String>,
530    /// Component status
531    pub status: ComponentStatus,
532    /// Component metadata
533    pub metadata: ComponentMetadata,
534}
535
536/// Component metadata
537#[derive(Debug, Clone, Serialize, Deserialize)]
538pub struct ComponentMetadata {
539    /// Component author
540    pub author: Option<String>,
541    /// Creation timestamp
542    pub created_at: String,
543    /// Last modified timestamp
544    pub modified_at: String,
545    /// Component tags
546    pub tags: Vec<String>,
547    /// Custom properties
548    pub properties: HashMap<String, String>,
549}
550
551/// Component status
552#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
553pub enum ComponentStatus {
554    /// Component is inactive
555    Inactive,
556    /// Component is initializing
557    Initializing,
558    /// Component is active and running
559    Active,
560    /// Component is paused
561    Paused,
562    /// Component is stopping
563    Stopping,
564    /// Component has failed
565    Failed,
566    /// Component is in error state
567    Error(String),
568}
569
570/// Component node in the dependency graph
571#[derive(Debug, Clone, Serialize, Deserialize)]
572pub struct ComponentNode {
573    /// Node identifier
574    pub id: String,
575    /// Component information
576    pub component: ComponentInfo,
577    /// Dependencies
578    pub dependencies: Vec<String>,
579    /// Dependents (reverse dependencies)
580    pub dependents: Vec<String>,
581    /// Node level in the dependency graph
582    pub level: usize,
583}
584
585/// Capability mismatch error
586#[derive(Debug, Clone, Serialize, Deserialize)]
587pub struct CapabilityMismatch {
588    /// Required capability
589    pub required: String,
590    /// Available capability
591    pub available: Option<String>,
592    /// Mismatch description
593    pub description: String,
594    /// Severity level
595    pub severity: CapabilityMismatchSeverity,
596}
597
598/// Capability mismatch severity
599#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
600pub enum CapabilityMismatchSeverity {
601    /// Warning level mismatch
602    Warning,
603    /// Error level mismatch
604    Error,
605    /// Critical level mismatch
606    Critical,
607}
608
609/// Compatibility report
610#[derive(Debug, Clone, Serialize, Deserialize)]
611pub struct CompatibilityReport {
612    /// Whether components are compatible
613    pub is_compatible: bool,
614    /// Compatibility score (0.0 to 1.0)
615    pub compatibility_score: f32,
616    /// List of capability mismatches
617    pub mismatches: Vec<CapabilityMismatch>,
618    /// Compatibility warnings
619    pub warnings: Vec<String>,
620    /// Report generation timestamp
621    pub generated_at: String,
622}
623
624/// Environment settings for component execution
625#[derive(Debug, Clone, Serialize, Deserialize)]
626pub struct EnvironmentSettings {
627    /// Environment name
628    pub name: String,
629    /// Environment variables
630    pub variables: HashMap<String, String>,
631    /// Working directory
632    pub working_directory: Option<String>,
633    /// Resource limits
634    pub resource_limits: Option<ResourceLimits>,
635    /// Security settings
636    pub security_settings: Option<SecuritySettings>,
637}
638
639/// Security settings
640#[derive(Debug, Clone, Serialize, Deserialize)]
641pub struct SecuritySettings {
642    /// Enable sandboxing
643    pub sandbox_enabled: bool,
644    /// Allowed network access
645    pub network_access: bool,
646    /// Allowed file system access
647    pub filesystem_access: bool,
648    /// Security policy
649    pub policy: Option<String>,
650}
651
652/// Execution condition for conditional component execution
653#[derive(Debug, Clone, Serialize, Deserialize)]
654pub struct ExecutionCondition {
655    /// Condition expression
656    pub expression: String,
657    /// Condition variables
658    pub variables: HashMap<String, String>,
659    /// Condition type
660    pub condition_type: ExecutionConditionType,
661}
662
663/// Execution condition types
664#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
665pub enum ExecutionConditionType {
666    /// Always execute
667    Always,
668    /// Never execute
669    Never,
670    /// Execute based on expression
671    Expression,
672    /// Execute based on dependency status
673    DependencyBased,
674    /// Execute based on resource availability
675    ResourceBased,
676}
677
678/// Execution metadata
679#[derive(Debug, Clone, Serialize, Deserialize)]
680pub struct ExecutionMetadata {
681    /// Execution ID
682    pub execution_id: String,
683    /// Start timestamp
684    pub start_time: String,
685    /// End timestamp
686    pub end_time: Option<String>,
687    /// Execution duration in milliseconds
688    pub duration_ms: Option<u64>,
689    /// Execution status
690    pub status: ExecutionStatus,
691    /// Resource usage
692    pub resource_usage: Option<ResourceUsage>,
693}
694
695/// Execution status
696#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
697pub enum ExecutionStatus {
698    /// Execution is pending
699    Pending,
700    /// Execution is running
701    Running,
702    /// Execution completed successfully
703    Completed,
704    /// Execution failed
705    Failed,
706    /// Execution was cancelled
707    Cancelled,
708    /// Execution timed out
709    TimedOut,
710}
711
712/// Resource usage information
713#[derive(Debug, Clone, Serialize, Deserialize)]
714pub struct ResourceUsage {
715    /// CPU usage percentage
716    pub cpu_usage: f32,
717    /// Memory usage in MB
718    pub memory_usage_mb: f32,
719    /// Disk usage in MB
720    pub disk_usage_mb: f32,
721    /// Network usage in MB
722    pub network_usage_mb: f32,
723}
724
725/// Log level for component logging
726#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
727pub enum LogLevel {
728    /// Trace level
729    Trace,
730    /// Debug level
731    Debug,
732    /// Info level
733    Info,
734    /// Warning level
735    Warn,
736    /// Error level
737    Error,
738    /// Critical level
739    Critical,
740}
741
742/// Missing dependency error
743#[derive(Debug, Clone, Serialize, Deserialize)]
744pub struct MissingDependency {
745    /// Component that has the missing dependency
746    pub component_id: String,
747    /// Missing dependency name
748    pub dependency_name: String,
749    /// Required version
750    pub required_version: Option<String>,
751    /// Suggested resolution
752    pub suggested_resolution: Option<String>,
753}
754
755/// Version conflict error
756#[derive(Debug, Clone, Serialize, Deserialize)]
757pub struct VersionConflict {
758    /// Component with version conflict
759    pub component_id: String,
760    /// Required version
761    pub required_version: String,
762    /// Available version
763    pub available_version: String,
764    /// Conflict description
765    pub description: String,
766}
767
768/// Resource limits for component execution
769#[derive(Debug, Clone, Serialize, Deserialize)]
770pub struct ResourceLimits {
771    /// Maximum CPU cores
772    pub max_cpu_cores: Option<usize>,
773    /// Maximum memory in MB
774    pub max_memory_mb: Option<usize>,
775    /// Maximum disk space in MB
776    pub max_disk_mb: Option<usize>,
777    /// Maximum network bandwidth in Mbps
778    pub max_network_mbps: Option<f32>,
779    /// Execution timeout in seconds
780    pub timeout_sec: Option<u64>,
781}
782
783impl Default for ComponentStatus {
784    fn default() -> Self {
785        Self::Inactive
786    }
787}
788
789impl Default for CapabilityMismatchSeverity {
790    fn default() -> Self {
791        Self::Warning
792    }
793}
794
795impl Default for ExecutionConditionType {
796    fn default() -> Self {
797        Self::Always
798    }
799}
800
801impl Default for ExecutionStatus {
802    fn default() -> Self {
803        Self::Pending
804    }
805}
806
807impl Default for LogLevel {
808    fn default() -> Self {
809        Self::Info
810    }
811}
812
813#[allow(non_snake_case)]
814#[cfg(test)]
815mod tests {
816    use super::*;
817
818    /// Mock component for testing
819    struct MockComponent {
820        id: String,
821        component_type: String,
822        state: ComponentState,
823        metrics: ComponentMetrics,
824    }
825
826    impl MockComponent {
827        fn new(id: &str, component_type: &str) -> Self {
828            Self {
829                id: id.to_string(),
830                component_type: component_type.to_string(),
831                state: ComponentState::Created,
832                metrics: ComponentMetrics::new(),
833            }
834        }
835    }
836
837    impl PluggableComponent for MockComponent {
838        fn initialize(&mut self, _config: &ComponentConfig) -> SklResult<()> {
839            self.state = ComponentState::Ready;
840            Ok(())
841        }
842
843        fn start(&mut self) -> SklResult<()> {
844            self.state = ComponentState::Running;
845            Ok(())
846        }
847
848        fn stop(&mut self) -> SklResult<()> {
849            self.state = ComponentState::Stopped;
850            Ok(())
851        }
852
853        fn pause(&mut self) -> SklResult<()> {
854            self.state = ComponentState::Paused;
855            Ok(())
856        }
857
858        fn resume(&mut self) -> SklResult<()> {
859            self.state = ComponentState::Running;
860            Ok(())
861        }
862
863        fn component_id(&self) -> &str {
864            &self.id
865        }
866
867        fn component_type(&self) -> &str {
868            &self.component_type
869        }
870
871        fn version(&self) -> &str {
872            "1.0.0"
873        }
874
875        fn current_state(&self) -> ComponentState {
876            self.state.clone()
877        }
878
879        fn health_check(&self) -> SklResult<HealthStatus> {
880            Ok(HealthStatus::Healthy)
881        }
882
883        fn capabilities(&self) -> Vec<ComponentCapability> {
884            vec![ComponentCapability {
885                name: "test_capability".to_string(),
886                description: "Test capability".to_string(),
887                required_config: vec![],
888                optional_config: vec![],
889                version: "1.0.0".to_string(),
890            }]
891        }
892
893        fn dependencies(&self) -> Vec<ComponentDependency> {
894            vec![]
895        }
896
897        fn validate_config(&self, _config: &ComponentConfig) -> SklResult<()> {
898            Ok(())
899        }
900
901        fn get_metrics(&self) -> ComponentMetrics {
902            self.metrics.clone()
903        }
904
905        fn handle_event(&mut self, _event: &ComponentEvent) -> SklResult<()> {
906            Ok(())
907        }
908
909        fn clone_component(&self) -> Box<dyn PluggableComponent> {
910            Box::new(MockComponent::new(&self.id, &self.component_type))
911        }
912
913        fn as_any(&self) -> &dyn Any {
914            self
915        }
916
917        fn as_any_mut(&mut self) -> &mut dyn Any {
918            self
919        }
920    }
921
922    /// Mock factory for testing
923    struct MockFactory;
924
925    impl ComponentFactory for MockFactory {
926        fn create_component(
927            &self,
928            config: &ComponentConfig,
929        ) -> SklResult<Box<dyn PluggableComponent>> {
930            Ok(Box::new(MockComponent::new(
931                &config.component_id,
932                &config.component_type,
933            )))
934        }
935
936        fn supported_types(&self) -> Vec<String> {
937            vec!["mock_component".to_string()]
938        }
939
940        fn validate_config(&self, _config: &ComponentConfig) -> SklResult<()> {
941            Ok(())
942        }
943
944        fn factory_metadata(&self) -> FactoryMetadata {
945            /// FactoryMetadata
946            FactoryMetadata {
947                name: "MockFactory".to_string(),
948                version: "1.0.0".to_string(),
949                supported_types: vec!["mock_component".to_string()],
950                description: "Mock factory for testing".to_string(),
951            }
952        }
953    }
954
955    #[test]
956    fn test_component_config_creation() {
957        let config = ComponentConfig::new("test_component", "test_type")
958            .with_parameter("param1", ConfigValue::String("value1".to_string()))
959            .with_environment("ENV_VAR", "env_value")
960            .with_feature("feature1", true);
961
962        assert_eq!(config.component_id, "test_component");
963        assert_eq!(config.component_type, "test_type");
964        assert!(config.is_feature_enabled("feature1"));
965        assert_eq!(config.get_environment("ENV_VAR"), Some("env_value"));
966    }
967
968    #[test]
969    fn test_component_lifecycle() {
970        let mut component = MockComponent::new("test", "mock");
971        let config = ComponentConfig::new("test", "mock");
972
973        assert_eq!(component.current_state(), ComponentState::Created);
974
975        component.initialize(&config).unwrap();
976        assert_eq!(component.current_state(), ComponentState::Ready);
977
978        component.start().unwrap();
979        assert_eq!(component.current_state(), ComponentState::Running);
980
981        component.pause().unwrap();
982        assert_eq!(component.current_state(), ComponentState::Paused);
983
984        component.resume().unwrap();
985        assert_eq!(component.current_state(), ComponentState::Running);
986
987        component.stop().unwrap();
988        assert_eq!(component.current_state(), ComponentState::Stopped);
989    }
990
991    #[test]
992    fn test_component_registry() {
993        let mut registry = ComponentRegistry::new();
994        let factory = Arc::new(MockFactory);
995
996        registry
997            .register_factory("mock_component", factory)
998            .unwrap();
999        assert!(registry.is_registered("mock_component"));
1000
1001        let config = ComponentConfig::new("test_instance", "mock_component");
1002        let component = registry
1003            .create_component("mock_component", &config)
1004            .unwrap();
1005
1006        assert_eq!(component.component_id(), "test_instance");
1007        assert_eq!(component.component_type(), "mock_component");
1008    }
1009
1010    #[test]
1011    fn test_component_metrics() {
1012        let mut metrics = ComponentMetrics::new();
1013        metrics.processed_requests = 100;
1014        metrics.failed_requests = 5;
1015
1016        assert_eq!(metrics.success_rate(), 0.95);
1017
1018        metrics.add_custom_metric("test_metric", MetricValue::Counter(42));
1019        assert!(metrics.custom_metrics.contains_key("test_metric"));
1020    }
1021}