system_analysis/
capabilities.rs

1//! Hardware capability analysis and profiling.
2
3use crate::resources::{ResourceType, CapabilityLevel, ResourceAmount};
4use crate::types::{SystemInfo, CpuInfo, GpuInfo, MemoryInfo, StorageInfo, NetworkInfo};
5use serde::{Deserialize, Serialize};
6
7/// Comprehensive capability profile for a system
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CapabilityProfile {
10    /// CPU capabilities
11    pub cpu_capabilities: CpuCapabilities,
12    /// GPU capabilities
13    pub gpu_capabilities: GpuCapabilities,
14    /// Memory capabilities
15    pub memory_capabilities: MemoryCapabilities,
16    /// Storage capabilities
17    pub storage_capabilities: StorageCapabilities,
18    /// Network capabilities
19    pub network_capabilities: NetworkCapabilities,
20    /// Overall capability scores
21    pub scores: CapabilityScores,
22    /// Capability metadata
23    pub metadata: CapabilityMetadata,
24}
25
26impl CapabilityProfile {
27    /// Create a capability profile from system information
28    pub fn from_system_info(system_info: &SystemInfo) -> Self {
29        let cpu_capabilities = CpuCapabilities::from_cpu_info(&system_info.cpu_info);
30        let gpu_capabilities = GpuCapabilities::from_gpu_info(&system_info.gpu_info);
31        let memory_capabilities = MemoryCapabilities::from_memory_info(&system_info.memory_info);
32        let storage_capabilities = StorageCapabilities::from_storage_info(&system_info.storage_info);
33        let network_capabilities = NetworkCapabilities::from_network_info(&system_info.network_info);
34
35        let scores = CapabilityScores::calculate(
36            &cpu_capabilities,
37            &gpu_capabilities,
38            &memory_capabilities,
39            &storage_capabilities,
40            &network_capabilities,
41        );
42
43        let metadata = CapabilityMetadata {
44            analysis_version: "1.0".to_string(),
45            created_at: chrono::Utc::now(),
46            system_fingerprint: Self::generate_fingerprint(system_info),
47        };
48
49        Self {
50            cpu_capabilities,
51            gpu_capabilities,
52            memory_capabilities,
53            storage_capabilities,
54            network_capabilities,
55            scores,
56            metadata,
57        }
58    }
59
60    /// Generate a unique fingerprint for the system
61    fn generate_fingerprint(system_info: &SystemInfo) -> String {
62        use std::collections::hash_map::DefaultHasher;
63        use std::hash::{Hash, Hasher};
64
65        let mut hasher = DefaultHasher::new();
66        system_info.cpu_info.brand.hash(&mut hasher);
67        system_info.cpu_info.physical_cores.hash(&mut hasher);
68        system_info.memory_info.total_ram.hash(&mut hasher);
69        
70        for gpu in &system_info.gpu_info {
71            gpu.name.hash(&mut hasher);
72            gpu.vendor.hash(&mut hasher);
73        }
74
75        format!("{:x}", hasher.finish())
76    }
77
78    /// Get capability level for a specific resource type
79    pub fn get_capability_level(&self, resource_type: &ResourceType) -> CapabilityLevel {
80        match resource_type {
81            ResourceType::CPU => self.scores.cpu_score.into(),
82            ResourceType::GPU => self.scores.gpu_score.into(),
83            ResourceType::Memory => self.scores.memory_score.into(),
84            ResourceType::Storage => self.scores.storage_score.into(),
85            ResourceType::Network => self.scores.network_score.into(),
86            ResourceType::Custom(_) => CapabilityLevel::Medium, // Default for custom types
87        }
88    }
89
90    /// Get resource amount for a specific resource type
91    pub fn get_resource_amount(&self, resource_type: &ResourceType) -> Option<ResourceAmount> {
92        match resource_type {
93            ResourceType::CPU => Some(ResourceAmount::Score(self.scores.cpu_score)),
94            ResourceType::GPU => Some(ResourceAmount::Score(self.scores.gpu_score)),
95            ResourceType::Memory => Some(ResourceAmount::Gigabytes(
96                self.memory_capabilities.total_ram_gb
97            )),
98            ResourceType::Storage => Some(ResourceAmount::Gigabytes(
99                self.storage_capabilities.total_capacity_gb
100            )),
101            ResourceType::Network => Some(ResourceAmount::Score(self.scores.network_score)),
102            ResourceType::Custom(_) => None,
103        }
104    }
105
106    /// Check if system supports specific features
107    pub fn supports_feature(&self, feature: &SystemFeature) -> bool {
108        match feature {
109            SystemFeature::CudaCompute => self.gpu_capabilities.cuda_support,
110            SystemFeature::OpenCLCompute => self.gpu_capabilities.opencl_support,
111            SystemFeature::AVXInstructions => self.cpu_capabilities.avx_support,
112            SystemFeature::NVMeStorage => self.storage_capabilities.nvme_support,
113            SystemFeature::HighBandwidthMemory => self.memory_capabilities.high_bandwidth,
114            SystemFeature::VirtualizationSupport => self.cpu_capabilities.virtualization_support,
115            SystemFeature::HighSpeedNetwork => self.network_capabilities.high_speed_support,
116        }
117    }
118}
119
120/// CPU-specific capabilities
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct CpuCapabilities {
123    /// Number of physical cores
124    pub physical_cores: usize,
125    /// Number of logical cores
126    pub logical_cores: usize,
127    /// Base frequency in MHz
128    pub base_frequency_mhz: u64,
129    /// Maximum frequency in MHz
130    pub max_frequency_mhz: Option<u64>,
131    /// Cache size in MB
132    pub cache_size_mb: Option<u64>,
133    /// Architecture family
134    pub architecture: String,
135    /// Instruction set extensions
136    pub instruction_sets: Vec<String>,
137    /// AVX support
138    pub avx_support: bool,
139    /// Virtualization support
140    pub virtualization_support: bool,
141    /// Thread performance score (0-10)
142    pub thread_performance: f64,
143    /// Multi-core efficiency (0-10)
144    pub multicore_efficiency: f64,
145}
146
147impl CpuCapabilities {
148    /// Create CPU capabilities from CPU info
149    pub fn from_cpu_info(cpu_info: &CpuInfo) -> Self {
150        let avx_support = cpu_info.brand.to_lowercase().contains("intel") || 
151                         cpu_info.brand.to_lowercase().contains("amd");
152        
153        let virtualization_support = cpu_info.logical_cores > cpu_info.physical_cores;
154        
155        let thread_performance = Self::calculate_thread_performance(cpu_info);
156        let multicore_efficiency = Self::calculate_multicore_efficiency(cpu_info);
157        
158        Self {
159            physical_cores: cpu_info.physical_cores,
160            logical_cores: cpu_info.logical_cores,
161            base_frequency_mhz: cpu_info.base_frequency,
162            max_frequency_mhz: cpu_info.max_frequency,
163            cache_size_mb: cpu_info.cache_size,
164            architecture: cpu_info.architecture.clone(),
165            instruction_sets: vec![], // Would be populated from CPUID in real implementation
166            avx_support,
167            virtualization_support,
168            thread_performance,
169            multicore_efficiency,
170        }
171    }
172
173    /// Calculate thread performance score
174    fn calculate_thread_performance(cpu_info: &CpuInfo) -> f64 {
175        let base_score = (cpu_info.base_frequency as f64 / 1000.0).min(5.0); // Up to 5 points for frequency
176        let cache_bonus = cpu_info.cache_size.map(|c| (c as f64 / 16.0).min(2.0)).unwrap_or(0.0); // Up to 2 points for cache
177        let arch_bonus = if cpu_info.architecture.contains("x86_64") { 1.0 } else { 0.5 };
178        
179        (base_score + cache_bonus + arch_bonus).min(10.0)
180    }
181
182    /// Calculate multicore efficiency score
183    fn calculate_multicore_efficiency(cpu_info: &CpuInfo) -> f64 {
184        let core_score = (cpu_info.physical_cores as f64 / 2.0).min(5.0); // Up to 5 points for cores
185        let hyperthreading_bonus = if cpu_info.logical_cores > cpu_info.physical_cores { 2.0 } else { 0.0 };
186        let architecture_bonus = if cpu_info.architecture.contains("x86_64") { 1.0 } else { 0.5 };
187        
188        (core_score + hyperthreading_bonus + architecture_bonus).min(10.0)
189    }
190
191    /// Get AI capability level based on CPU performance
192    pub fn ai_capability_level(&self) -> crate::resources::CapabilityLevel {
193        let combined_score = (self.thread_performance + self.multicore_efficiency) / 2.0;
194        crate::resources::CapabilityLevel::from_numeric(combined_score)
195    }
196}
197
198/// GPU-specific capabilities
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct GpuCapabilities {
201    /// Available GPUs
202    pub gpus: Vec<GpuDevice>,
203    /// Best GPU for compute
204    pub primary_compute_gpu: Option<usize>,
205    /// Total VRAM across all GPUs
206    pub total_vram_gb: f64,
207    /// CUDA support available
208    pub cuda_support: bool,
209    /// OpenCL support available
210    pub opencl_support: bool,
211    /// AI acceleration score (0-10)
212    pub ai_acceleration_score: f64,
213    /// Graphics performance score (0-10)
214    pub graphics_score: f64,
215    /// Compute performance score (0-10)
216    pub compute_score: f64,
217}
218
219impl GpuCapabilities {
220    /// Create GPU capabilities from GPU info
221    pub fn from_gpu_info(gpu_info: &[GpuInfo]) -> Self {
222        let gpus: Vec<GpuDevice> = gpu_info.iter().map(GpuDevice::from_gpu_info).collect();
223        
224        let total_vram_gb = gpus.iter()
225            .map(|gpu| gpu.vram_gb.unwrap_or(0.0))
226            .sum();
227        
228        let cuda_support = gpus.iter().any(|gpu| gpu.cuda_support);
229        let opencl_support = gpus.iter().any(|gpu| gpu.opencl_support);
230        
231        let primary_compute_gpu = Self::find_best_compute_gpu(&gpus);
232        
233        let ai_acceleration_score = Self::calculate_ai_score(&gpus);
234        let graphics_score = Self::calculate_graphics_score(&gpus);
235        let compute_score = Self::calculate_compute_score(&gpus);
236        
237        Self {
238            gpus,
239            primary_compute_gpu,
240            total_vram_gb,
241            cuda_support,
242            opencl_support,
243            ai_acceleration_score,
244            graphics_score,
245            compute_score,
246        }
247    }
248
249    /// Find the best GPU for compute workloads
250    fn find_best_compute_gpu(gpus: &[GpuDevice]) -> Option<usize> {
251        gpus.iter()
252            .enumerate()
253            .max_by(|(_, a), (_, b)| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
254            .map(|(idx, _)| idx)
255    }
256
257    /// Calculate AI acceleration score
258    fn calculate_ai_score(gpus: &[GpuDevice]) -> f64 {
259        if gpus.is_empty() {
260            return 0.0;
261        }
262
263        let best_gpu = gpus.iter()
264            .max_by(|a, b| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
265            .unwrap();
266
267        let vram_score = best_gpu.vram_gb.map(|v| (v / 8.0).min(4.0)).unwrap_or(0.0); // Up to 4 points for VRAM
268        let vendor_bonus = if best_gpu.vendor.to_lowercase().contains("nvidia") { 3.0 } else { 1.0 };
269        let cuda_bonus = if best_gpu.cuda_support { 2.0 } else { 0.0 };
270        
271        (vram_score + vendor_bonus + cuda_bonus).min(10.0)
272    }
273
274    /// Calculate graphics performance score
275    fn calculate_graphics_score(gpus: &[GpuDevice]) -> f64 {
276        if gpus.is_empty() {
277            return 0.0;
278        }
279
280        let best_gpu = gpus.iter()
281            .max_by(|a, b| a.graphics_score.partial_cmp(&b.graphics_score).unwrap())
282            .unwrap();
283
284        best_gpu.graphics_score
285    }
286
287    /// Calculate compute performance score
288    fn calculate_compute_score(gpus: &[GpuDevice]) -> f64 {
289        if gpus.is_empty() {
290            return 0.0;
291        }
292
293        let best_gpu = gpus.iter()
294            .max_by(|a, b| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
295            .unwrap();
296
297        best_gpu.compute_capability_score
298    }
299}
300
301/// Individual GPU device capabilities
302#[derive(Debug, Clone, Serialize, Deserialize)]
303pub struct GpuDevice {
304    /// GPU name
305    pub name: String,
306    /// GPU vendor
307    pub vendor: String,
308    /// VRAM in GB
309    pub vram_gb: Option<f64>,
310    /// Compute capability
311    pub compute_capability: Option<String>,
312    /// CUDA support
313    pub cuda_support: bool,
314    /// OpenCL support
315    pub opencl_support: bool,
316    /// Graphics performance score (0-10)
317    pub graphics_score: f64,
318    /// Compute capability score (0-10)
319    pub compute_capability_score: f64,
320    /// Power efficiency score (0-10)
321    pub power_efficiency: f64,
322}
323
324impl GpuDevice {
325    /// Create GPU device from GPU info
326    pub fn from_gpu_info(gpu_info: &GpuInfo) -> Self {
327        let vram_gb = gpu_info.vram_size.map(|v| v as f64 / 1024.0);
328        
329        let graphics_score = Self::calculate_graphics_score_for_device(gpu_info);
330        let compute_score = Self::calculate_compute_score_for_device(gpu_info);
331        let power_efficiency = Self::calculate_power_efficiency(gpu_info);
332        
333        Self {
334            name: gpu_info.name.clone(),
335            vendor: gpu_info.vendor.clone(),
336            vram_gb,
337            compute_capability: gpu_info.compute_capability.clone(),
338            cuda_support: gpu_info.cuda_support,
339            opencl_support: gpu_info.opencl_support,
340            graphics_score,
341            compute_capability_score: compute_score,
342            power_efficiency,
343        }
344    }
345
346    /// Calculate graphics score for individual device
347    fn calculate_graphics_score_for_device(gpu_info: &GpuInfo) -> f64 {
348        let vram_score = gpu_info.vram_size.map(|v| (v as f64 / 1024.0 / 4.0).min(3.0)).unwrap_or(0.0);
349        let vendor_score = match gpu_info.vendor.to_lowercase().as_str() {
350            vendor if vendor.contains("nvidia") => 4.0,
351            vendor if vendor.contains("amd") => 3.5,
352            vendor if vendor.contains("intel") => 2.0,
353            _ => 1.0,
354        };
355        let modern_bonus = if gpu_info.name.contains("RTX") || gpu_info.name.contains("RX") { 2.0 } else { 0.0 };
356        
357        (vram_score + vendor_score + modern_bonus).min(10.0)
358    }
359
360    /// Calculate compute score for individual device
361    fn calculate_compute_score_for_device(gpu_info: &GpuInfo) -> f64 {
362        let mut score = 0.0;
363        
364        // VRAM contribution
365        if let Some(vram) = gpu_info.vram_size {
366            score += (vram as f64 / 1024.0 / 8.0).min(4.0); // Up to 4 points for VRAM
367        }
368        
369        // CUDA support bonus
370        if gpu_info.cuda_support {
371            score += 3.0;
372        }
373        
374        // Vendor scoring
375        score += match gpu_info.vendor.to_lowercase().as_str() {
376            vendor if vendor.contains("nvidia") => 2.0,
377            vendor if vendor.contains("amd") => 1.5,
378            vendor if vendor.contains("intel") => 0.5,
379            _ => 0.0,
380        };
381        
382        // Modern architecture bonus
383        if gpu_info.name.contains("RTX") || gpu_info.name.contains("A100") || gpu_info.name.contains("H100") {
384            score += 1.0;
385        }
386        
387        score.min(10.0)
388    }
389
390    /// Calculate power efficiency score
391    fn calculate_power_efficiency(gpu_info: &GpuInfo) -> f64 {
392        // This would typically require power consumption data
393        // For now, use heuristics based on generation and vendor
394        match gpu_info.vendor.to_lowercase().as_str() {
395            vendor if vendor.contains("nvidia") && gpu_info.name.contains("RTX") => 8.0,
396            vendor if vendor.contains("amd") && gpu_info.name.contains("RX") => 7.0,
397            vendor if vendor.contains("intel") => 6.0,
398            _ => 5.0,
399        }
400    }
401}
402
403/// Memory-specific capabilities
404#[derive(Debug, Clone, Serialize, Deserialize)]
405pub struct MemoryCapabilities {
406    /// Total RAM in GB
407    pub total_ram_gb: f64,
408    /// Available RAM in GB
409    pub available_ram_gb: f64,
410    /// Memory type
411    pub memory_type: Option<String>,
412    /// Memory speed in MHz
413    pub memory_speed_mhz: Option<u64>,
414    /// Memory bandwidth score (0-10)
415    pub bandwidth_score: f64,
416    /// Memory capacity score (0-10)
417    pub capacity_score: f64,
418    /// High-bandwidth memory support
419    pub high_bandwidth: bool,
420    /// ECC memory support
421    pub ecc_support: bool,
422}
423
424impl MemoryCapabilities {
425    /// Create memory capabilities from memory info
426    pub fn from_memory_info(memory_info: &MemoryInfo) -> Self {
427        let total_ram_gb = memory_info.total_ram as f64 / 1024.0;
428        let available_ram_gb = memory_info.available_ram as f64 / 1024.0;
429        
430        let capacity_score = Self::calculate_capacity_score(total_ram_gb);
431        let bandwidth_score = Self::calculate_bandwidth_score(memory_info);
432        
433        let high_bandwidth = memory_info.memory_speed.map(|s| s >= 3200).unwrap_or(false);
434        let ecc_support = memory_info.memory_type.as_ref()
435            .map(|t| t.to_lowercase().contains("ecc"))
436            .unwrap_or(false);
437        
438        Self {
439            total_ram_gb,
440            available_ram_gb,
441            memory_type: memory_info.memory_type.clone(),
442            memory_speed_mhz: memory_info.memory_speed,
443            bandwidth_score,
444            capacity_score,
445            high_bandwidth,
446            ecc_support,
447        }
448    }
449
450    /// Calculate memory capacity score
451    fn calculate_capacity_score(total_gb: f64) -> f64 {
452        match total_gb {
453            gb if gb >= 128.0 => 10.0,
454            gb if gb >= 64.0 => 9.0,
455            gb if gb >= 32.0 => 8.0,
456            gb if gb >= 16.0 => 7.0,
457            gb if gb >= 8.0 => 5.0,
458            gb if gb >= 4.0 => 3.0,
459            _ => 1.0,
460        }
461    }
462
463    /// Calculate memory bandwidth score
464    fn calculate_bandwidth_score(memory_info: &MemoryInfo) -> f64 {
465        let speed_score = memory_info.memory_speed
466            .map(|speed| (speed as f64 / 800.0).min(5.0)) // Up to 5 points for speed
467            .unwrap_or(2.0);
468        
469        let type_bonus = memory_info.memory_type.as_ref()
470            .map(|t| match t.to_lowercase().as_str() {
471                t if t.contains("ddr5") => 3.0,
472                t if t.contains("ddr4") => 2.0,
473                t if t.contains("ddr3") => 1.0,
474                _ => 0.5,
475            })
476            .unwrap_or(1.0);
477        
478        (speed_score + type_bonus).min(10.0)
479    }
480}
481
482/// Storage-specific capabilities
483#[derive(Debug, Clone, Serialize, Deserialize)]
484pub struct StorageCapabilities {
485    /// Storage devices
486    pub devices: Vec<StorageDevice>,
487    /// Total capacity in GB
488    pub total_capacity_gb: f64,
489    /// Available capacity in GB
490    pub available_capacity_gb: f64,
491    /// Fastest device performance score (0-10)
492    pub performance_score: f64,
493    /// NVMe support
494    pub nvme_support: bool,
495    /// SSD ratio (percentage of storage that is SSD)
496    pub ssd_ratio: f64,
497}
498
499impl StorageCapabilities {
500    /// Create storage capabilities from storage info
501    pub fn from_storage_info(storage_info: &[StorageInfo]) -> Self {
502        let devices: Vec<StorageDevice> = storage_info.iter()
503            .map(StorageDevice::from_storage_info)
504            .collect();
505        
506        let total_capacity_gb = devices.iter()
507            .map(|d| d.total_capacity_gb)
508            .sum();
509        
510        let available_capacity_gb = devices.iter()
511            .map(|d| d.available_capacity_gb)
512            .sum();
513        
514        let performance_score = devices.iter()
515            .map(|d| d.performance_score)
516            .fold(0.0, f64::max);
517        
518        let nvme_support = devices.iter()
519            .any(|d| d.storage_type.to_lowercase().contains("nvme"));
520        
521        let ssd_capacity: f64 = devices.iter()
522            .filter(|d| d.is_ssd())
523            .map(|d| d.total_capacity_gb)
524            .sum();
525        
526        let ssd_ratio = if total_capacity_gb > 0.0 {
527            ssd_capacity / total_capacity_gb * 100.0
528        } else {
529            0.0
530        };
531        
532        Self {
533            devices,
534            total_capacity_gb,
535            available_capacity_gb,
536            performance_score,
537            nvme_support,
538            ssd_ratio,
539        }
540    }
541}
542
543/// Individual storage device capabilities
544#[derive(Debug, Clone, Serialize, Deserialize)]
545pub struct StorageDevice {
546    /// Device name
547    pub name: String,
548    /// Storage type
549    pub storage_type: String,
550    /// Total capacity in GB
551    pub total_capacity_gb: f64,
552    /// Available capacity in GB
553    pub available_capacity_gb: f64,
554    /// Read speed in MB/s
555    pub read_speed_mbps: Option<u64>,
556    /// Write speed in MB/s
557    pub write_speed_mbps: Option<u64>,
558    /// Performance score (0-10)
559    pub performance_score: f64,
560    /// Reliability score (0-10)
561    pub reliability_score: f64,
562}
563
564impl StorageDevice {
565    /// Create storage device from storage info
566    pub fn from_storage_info(storage_info: &StorageInfo) -> Self {
567        let performance_score = Self::calculate_performance_score(storage_info);
568        let reliability_score = Self::calculate_reliability_score(storage_info);
569        
570        Self {
571            name: storage_info.name.clone(),
572            storage_type: storage_info.storage_type.clone(),
573            total_capacity_gb: storage_info.total_capacity as f64,
574            available_capacity_gb: storage_info.available_capacity as f64,
575            read_speed_mbps: storage_info.read_speed,
576            write_speed_mbps: storage_info.write_speed,
577            performance_score,
578            reliability_score,
579        }
580    }
581
582    /// Check if this is an SSD
583    pub fn is_ssd(&self) -> bool {
584        let storage_type = self.storage_type.to_lowercase();
585        storage_type.contains("ssd") || storage_type.contains("nvme")
586    }
587
588    /// Calculate performance score
589    fn calculate_performance_score(storage_info: &StorageInfo) -> f64 {
590        let type_score = match storage_info.storage_type.to_lowercase().as_str() {
591            t if t.contains("nvme") => 8.0,
592            t if t.contains("ssd") => 6.0,
593            t if t.contains("hdd") => 2.0,
594            _ => 3.0,
595        };
596        
597        let speed_bonus = storage_info.read_speed
598            .map(|s| (s as f64 / 1000.0).min(2.0)) // Up to 2 points for read speed
599            .unwrap_or(0.0);
600        
601        (type_score + speed_bonus).min(10.0)
602    }
603
604    /// Calculate reliability score
605    fn calculate_reliability_score(storage_info: &StorageInfo) -> f64 {
606        match storage_info.storage_type.to_lowercase().as_str() {
607            t if t.contains("nvme") => 9.0,
608            t if t.contains("ssd") => 8.0,
609            t if t.contains("hdd") => 6.0,
610            _ => 5.0,
611        }
612    }
613}
614
615/// Network-specific capabilities
616#[derive(Debug, Clone, Serialize, Deserialize)]
617pub struct NetworkCapabilities {
618    /// Network interfaces
619    pub interfaces: Vec<NetworkInterface>,
620    /// Internet connectivity
621    pub internet_connected: bool,
622    /// Estimated bandwidth in Mbps
623    pub estimated_bandwidth_mbps: Option<u64>,
624    /// Network performance score (0-10)
625    pub performance_score: f64,
626    /// High-speed network support
627    pub high_speed_support: bool,
628    /// Latency estimate in milliseconds
629    pub estimated_latency_ms: Option<f64>,
630}
631
632impl NetworkCapabilities {
633    /// Create network capabilities from network info
634    pub fn from_network_info(network_info: &NetworkInfo) -> Self {
635        let interfaces: Vec<NetworkInterface> = network_info.interfaces.iter()
636            .map(NetworkInterface::from_network_interface_info)
637            .collect();
638        
639        let performance_score = Self::calculate_network_performance(&interfaces, network_info.estimated_bandwidth);
640        let high_speed_support = network_info.estimated_bandwidth
641            .map(|b| b >= 1000)
642            .unwrap_or(false);
643        
644        Self {
645            interfaces,
646            internet_connected: network_info.internet_connected,
647            estimated_bandwidth_mbps: network_info.estimated_bandwidth,
648            performance_score,
649            high_speed_support,
650            estimated_latency_ms: None, // Would need actual measurements
651        }
652    }
653
654    /// Calculate network performance score
655    fn calculate_network_performance(interfaces: &[NetworkInterface], bandwidth: Option<u64>) -> f64 {
656        let bandwidth_score = bandwidth
657            .map(|b| (b as f64 / 100.0).min(5.0)) // Up to 5 points for bandwidth
658            .unwrap_or(1.0);
659        
660        let interface_score = if interfaces.iter().any(|i| i.is_high_speed()) {
661            3.0
662        } else if interfaces.iter().any(|i| i.is_ethernet()) {
663            2.0
664        } else {
665            1.0
666        };
667        
668        let connection_bonus = if interfaces.iter().any(|i| !i.ip_addresses.is_empty()) {
669            2.0
670        } else {
671            0.0
672        };
673        
674        (bandwidth_score + interface_score + connection_bonus).min(10.0)
675    }
676}
677
678/// Network interface capabilities
679#[derive(Debug, Clone, Serialize, Deserialize)]
680pub struct NetworkInterface {
681    /// Interface name
682    pub name: String,
683    /// Interface type
684    pub interface_type: String,
685    /// MAC address
686    pub mac_address: String,
687    /// IP addresses
688    pub ip_addresses: Vec<String>,
689    /// Connection speed in Mbps
690    pub speed_mbps: Option<u64>,
691    /// Interface quality score (0-10)
692    pub quality_score: f64,
693}
694
695impl NetworkInterface {
696    /// Create network interface from network interface info
697    pub fn from_network_interface_info(interface_info: &crate::types::NetworkInterface) -> Self {
698        let quality_score = Self::calculate_quality_score(interface_info);
699        
700        Self {
701            name: interface_info.name.clone(),
702            interface_type: interface_info.interface_type.clone(),
703            mac_address: interface_info.mac_address.clone(),
704            ip_addresses: interface_info.ip_addresses.clone(),
705            speed_mbps: interface_info.speed,
706            quality_score,
707        }
708    }
709
710    /// Check if this is a high-speed interface
711    pub fn is_high_speed(&self) -> bool {
712        self.speed_mbps.map(|s| s >= 1000).unwrap_or(false)
713    }
714
715    /// Check if this is an Ethernet interface
716    pub fn is_ethernet(&self) -> bool {
717        self.interface_type.to_lowercase().contains("ethernet")
718    }
719
720    /// Calculate interface quality score
721    fn calculate_quality_score(interface_info: &crate::types::NetworkInterface) -> f64 {
722        let type_score = match interface_info.interface_type.to_lowercase().as_str() {
723            t if t.contains("ethernet") => 4.0,
724            t if t.contains("wifi") => 3.0,
725            t if t.contains("wireless") => 3.0,
726            _ => 2.0,
727        };
728        
729        let speed_score = interface_info.speed
730            .map(|s| (s as f64 / 500.0).min(3.0)) // Up to 3 points for speed
731            .unwrap_or(1.0);
732        
733        let connection_bonus = if !interface_info.ip_addresses.is_empty() {
734            3.0
735        } else {
736            0.0
737        };
738        
739        (type_score + speed_score + connection_bonus).min(10.0)
740    }
741}
742
743/// Overall capability scores
744#[derive(Debug, Clone, Serialize, Deserialize)]
745pub struct CapabilityScores {
746    /// CPU score (0-10)
747    pub cpu_score: f64,
748    /// GPU score (0-10)
749    pub gpu_score: f64,
750    /// Memory score (0-10)
751    pub memory_score: f64,
752    /// Storage score (0-10)
753    pub storage_score: f64,
754    /// Network score (0-10)
755    pub network_score: f64,
756    /// Overall system score (0-10)
757    pub overall_score: f64,
758}
759
760impl CapabilityScores {
761    /// Calculate scores from individual capabilities
762    pub fn calculate(
763        cpu: &CpuCapabilities,
764        gpu: &GpuCapabilities,
765        memory: &MemoryCapabilities,
766        storage: &StorageCapabilities,
767        network: &NetworkCapabilities,
768    ) -> Self {
769        let cpu_score = (cpu.thread_performance + cpu.multicore_efficiency) / 2.0;
770        let gpu_score = (gpu.ai_acceleration_score + gpu.compute_score) / 2.0;
771        let memory_score = (memory.capacity_score + memory.bandwidth_score) / 2.0;
772        let storage_score = storage.performance_score;
773        let network_score = network.performance_score;
774        
775        let overall_score = (cpu_score + gpu_score + memory_score + storage_score + network_score) / 5.0;
776        
777        Self {
778            cpu_score,
779            gpu_score,
780            memory_score,
781            storage_score,
782            network_score,
783            overall_score,
784        }
785    }
786}
787
788/// Capability analysis metadata
789#[derive(Debug, Clone, Serialize, Deserialize)]
790pub struct CapabilityMetadata {
791    /// Analysis version
792    pub analysis_version: String,
793    /// Creation timestamp
794    pub created_at: chrono::DateTime<chrono::Utc>,
795    /// System fingerprint for caching
796    pub system_fingerprint: String,
797}
798
799/// System features that can be checked
800#[derive(Debug, Clone, Copy, PartialEq, Eq)]
801pub enum SystemFeature {
802    /// CUDA compute support
803    CudaCompute,
804    /// OpenCL compute support
805    OpenCLCompute,
806    /// AVX instruction set support
807    AVXInstructions,
808    /// NVMe storage support
809    NVMeStorage,
810    /// High-bandwidth memory
811    HighBandwidthMemory,
812    /// Virtualization support
813    VirtualizationSupport,
814    /// High-speed network (1Gbps+)
815    HighSpeedNetwork,
816}
817#[cfg(test)]
818mod tests {
819    use super::*;
820    use crate::types::{CpuInfo, MemoryInfo, StorageInfo, NetworkInfo, NetworkInterface};
821
822    #[test]
823    fn test_cpu_capability_creation() {
824        let cpu_info = CpuInfo {
825            brand: "Intel Core i7-8700K".to_string(),
826            physical_cores: 6,
827            logical_cores: 12,
828            base_frequency: 3700,
829            max_frequency: Some(4700),
830            cache_size: Some(12288),
831            architecture: "x86_64".to_string(),
832        };
833
834        let cpu_capability = CpuCapabilities::from_cpu_info(&cpu_info);
835        
836        assert_eq!(cpu_capability.architecture, "x86_64");
837        assert_eq!(cpu_capability.physical_cores, 6);
838        assert_eq!(cpu_capability.logical_cores, 12);
839        assert_eq!(cpu_capability.base_frequency_mhz, 3700);
840        assert!(cpu_capability.thread_performance > 0.0);
841        assert!(cpu_capability.multicore_efficiency > 0.0);
842    }
843
844    #[test]
845    fn test_memory_capability_creation() {
846        let memory_info = MemoryInfo {
847            total_ram: 16_000_000_000, // 16GB in bytes
848            available_ram: 12_000_000_000, // 12GB in bytes
849            memory_speed: Some(3200),
850            memory_type: Some("DDR4".to_string()),
851        };
852
853        let memory_capability = MemoryCapabilities::from_memory_info(&memory_info);
854        
855        assert!(memory_capability.total_ram_gb > 0.0);
856        assert!(memory_capability.available_ram_gb > 0.0);
857        assert_eq!(memory_capability.memory_type, Some("DDR4".to_string()));
858        assert!(memory_capability.bandwidth_score > 0.0);
859    }
860
861    #[test]
862    fn test_storage_capability_creation() {
863        let storage_info = vec![StorageInfo {
864            name: "Samsung SSD 970 EVO".to_string(),
865            storage_type: "NVMe SSD".to_string(),
866            total_capacity: 500,
867            available_capacity: 400,
868            read_speed: Some(3500),
869            write_speed: Some(3200),
870        }];
871
872        let storage_capability = StorageCapabilities::from_storage_info(&storage_info);
873        
874        assert!(storage_capability.total_capacity_gb > 0.0);
875        assert!(storage_capability.available_capacity_gb > 0.0);
876        assert!(storage_capability.nvme_support);
877        assert!(storage_capability.performance_score > 0.0);
878    }
879
880    #[test]
881    fn test_network_capability_creation() {
882        let network_info = NetworkInfo {
883            interfaces: vec![
884                NetworkInterface {
885                    name: "Ethernet".to_string(),
886                    interface_type: "Ethernet".to_string(),
887                    mac_address: "00:11:22:33:44:55".to_string(),
888                    ip_addresses: vec!["192.168.1.100".to_string()],
889                    speed: Some(1000),
890                }
891            ],
892            internet_connected: true,
893            estimated_bandwidth: Some(1000),
894        };
895
896        let network_capability = NetworkCapabilities::from_network_info(&network_info);
897        
898        assert!(network_capability.internet_connected);
899        assert!(network_capability.estimated_bandwidth_mbps.unwrap_or(0) > 0);
900        assert!(network_capability.performance_score > 0.0);
901    }
902
903    #[test]
904    fn test_capability_profile_creation() {
905        let cpu_info = CpuInfo {
906            brand: "Intel Core i5-8400".to_string(),
907            physical_cores: 6,
908            logical_cores: 6,
909            base_frequency: 2800,
910            max_frequency: Some(4000),
911            cache_size: Some(9216),
912            architecture: "x86_64".to_string(),
913        };
914
915        let memory_info = MemoryInfo {
916            total_ram: 8_000_000_000, // 8GB in bytes
917            available_ram: 6_000_000_000, // 6GB in bytes
918            memory_speed: Some(2666),
919            memory_type: Some("DDR4".to_string()),
920        };
921
922        let storage_info = vec![StorageInfo {
923            name: "Generic SSD".to_string(),
924            storage_type: "SSD".to_string(),
925            total_capacity: 256,
926            available_capacity: 200,
927            read_speed: Some(500),
928            write_speed: Some(450),
929        }];
930
931        let network_info = NetworkInfo {
932            interfaces: vec![],
933            internet_connected: false,
934            estimated_bandwidth: None,
935        };
936
937        let gpu_info = vec![];
938
939        let system_info = crate::types::SystemInfo {
940            os_name: "Windows".to_string(),
941            os_version: "11".to_string(),
942            cpu_info: cpu_info,
943            gpu_info: gpu_info,
944            memory_info: memory_info,
945            storage_info: storage_info,
946            network_info: network_info,
947        };
948
949        let capability_profile = CapabilityProfile::from_system_info(&system_info);
950        
951        assert!(capability_profile.scores.overall_score >= 0.0);
952        assert!(capability_profile.scores.overall_score <= 10.0);
953    }
954
955    #[test]
956    fn test_ai_capability_levels() {
957        // Test low-end system
958        let low_end_cpu = CpuInfo {
959            brand: "Intel Celeron".to_string(),
960            physical_cores: 2,
961            logical_cores: 2,
962            base_frequency: 1600,
963            max_frequency: Some(2400),
964            cache_size: Some(2048),
965            architecture: "x86_64".to_string(),
966        };
967
968        let low_capability = CpuCapabilities::from_cpu_info(&low_end_cpu);
969        let low_ai_level = low_capability.ai_capability_level();
970        
971        // Should be Very Low or Low for a Celeron
972        assert!(matches!(low_ai_level, CapabilityLevel::VeryLow | CapabilityLevel::Low));
973
974        // Test high-end system
975        let high_end_cpu = CpuInfo {
976            brand: "Intel Core i9-12900K".to_string(),
977            physical_cores: 16,
978            logical_cores: 24,
979            base_frequency: 3200,
980            max_frequency: Some(5200),
981            cache_size: Some(30720),
982            architecture: "x86_64".to_string(),
983        };
984
985        let high_capability = CpuCapabilities::from_cpu_info(&high_end_cpu);
986        let high_ai_level = high_capability.ai_capability_level();
987        
988        // Should be High or Very High for an i9
989        assert!(matches!(high_ai_level, CapabilityLevel::High | CapabilityLevel::VeryHigh));
990    }
991}