1use async_trait::async_trait;
8use blake3;
9use dashmap::{DashMap, DashSet};
10use once_cell::sync::Lazy;
11use rayon::iter::{ParallelBridge, ParallelIterator};
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14use std::sync::{
15 atomic::{AtomicU32, AtomicU64, Ordering},
16 Arc, RwLock,
17};
18use std::time::{SystemTime, UNIX_EPOCH};
19use walkdir::WalkDir;
20
21use super::AgentError;
22
23#[derive(Debug)]
25pub struct SystemIndex {
26 pub agent_ids: DashSet<String>,
28 pub component_paths: DashMap<String, (String, [u8; 32])>,
30 pub model_paths: DashMap<String, semver::Version>,
32 pub documentation_links: DashMap<String, (LinkStatus, [u8; 32])>,
34 pub last_updated: AtomicU64,
36 pub version: AtomicU32,
38 pub rust_metrics: DashMap<String, RustCodeMetrics>,
40}
41
42impl Default for SystemIndex {
43 fn default() -> Self {
44 Self {
45 agent_ids: DashSet::new(),
46 component_paths: DashMap::new(),
47 model_paths: DashMap::new(),
48 documentation_links: DashMap::new(),
49 last_updated: AtomicU64::new(0),
50 version: AtomicU32::new(0),
51 rust_metrics: DashMap::new(),
52 }
53 }
54}
55
56#[derive(Debug, Default, Clone)]
58pub struct SystemMap {
59 pub agent_relationships: HashMap<String, Vec<String>>,
61
62 pub component_states: HashMap<String, ComponentState>,
64
65 pub model_states: HashMap<String, ModelState>,
67
68 pub health_metrics: HashMap<String, f64>,
70
71 pub last_updated: u64,
73
74 pub version: u32,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct ComponentState {
81 pub id: String,
83
84 pub status: ComponentStatus,
86
87 pub health: f32,
89
90 pub last_updated: u64,
92
93 pub properties: HashMap<String, serde_json::Value>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
99pub enum ComponentStatus {
100 Active,
102
103 Initializing,
105
106 Degraded,
108
109 Offline,
111
112 Maintenance,
114
115 Unknown,
117}
118
119impl Default for ComponentStatus {
120 fn default() -> Self {
121 Self::Unknown
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct ModelState {
128 pub id: String,
130
131 pub version: String,
133
134 pub status: ModelStatus,
136
137 pub accuracy: f32,
139
140 pub last_updated: u64,
142
143 pub metadata: HashMap<String, serde_json::Value>,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
149pub enum ModelStatus {
150 Ready,
152
153 Training,
155
156 Validating,
158
159 Failed,
161
162 Updating,
164
165 Deprecated,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
171pub enum LinkStatus {
172 Valid,
173 Broken,
174 Deprecated(String), External,
176}
177
178#[derive(Debug, Clone, Default, Serialize, Deserialize)]
180pub struct RustCodeMetrics {
181 pub cyclomatic_complexity: f32,
182 pub unsafe_usage_count: u32,
183 pub test_coverage: f32,
184 pub dependency_graph: HashMap<String, Vec<String>>,
185 pub clippy_lints: HashMap<String, u32>,
186 pub security_audit_flags: Vec<String>,
187 pub bitcoin_protocol_adherence: f32,
188}
189
190static GLOBAL_INDEX: Lazy<Arc<SystemIndexManager>> =
192 Lazy::new(|| Arc::new(SystemIndexManager::new()));
193
194static GLOBAL_MAP: Lazy<Arc<SystemMapManager>> = Lazy::new(|| Arc::new(SystemMapManager::new()));
196
197pub struct SystemIndexManager {
199 index: RwLock<SystemIndex>,
200}
201
202impl Default for SystemIndexManager {
203 fn default() -> Self {
204 Self::new()
205 }
206}
207
208impl SystemIndexManager {
209 pub fn new() -> Self {
211 Self {
212 index: RwLock::new(SystemIndex::default()),
213 }
214 }
215
216 pub async fn read_index(&self) -> Result<(), AgentError> {
218 let _index = self.index.read().map_err(|_| {
219 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
220 })?;
221 Ok(())
223 }
224
225 async fn get_index_for_reading(&self) -> Result<SystemIndex, AgentError> {
227 let index = self.index.read().map_err(|_| {
228 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
229 })?;
230
231 let new_index = SystemIndex::default();
233 for entry in index.component_paths.iter() {
234 new_index
235 .component_paths
236 .insert(entry.key().clone(), entry.value().clone());
237 }
238 for entry in index.agent_ids.iter() {
239 new_index.agent_ids.insert(entry.clone());
240 }
241 for entry in index.model_paths.iter() {
242 new_index
243 .model_paths
244 .insert(entry.key().clone(), entry.value().clone());
245 }
246 Ok(new_index)
247 }
248
249 pub async fn get_agent_ids(&self) -> Result<Vec<String>, AgentError> {
251 let index = self.index.read().map_err(|_| {
252 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
253 })?;
254 let agents: Vec<String> = index.agent_ids.iter().map(|id| id.clone()).collect();
255 Ok(agents)
256 }
257
258 pub async fn increment_version(&self) -> Result<(), AgentError> {
260 let index = self.index.read().map_err(|_| {
261 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
262 })?;
263
264 index
265 .version
266 .store(index.version.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
267 index.last_updated.store(
268 SystemTime::now()
269 .duration_since(UNIX_EPOCH)
270 .map_err(AgentError::SystemTimeError)?
271 .as_nanos() as u64,
272 Ordering::SeqCst,
273 );
274
275 Ok(())
276 }
277
278 pub async fn register_agent(&self, agent_id: String) -> Result<(), AgentError> {
280 let index = self.index.read().map_err(|_| {
281 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
282 })?;
283 index.agent_ids.insert(agent_id);
284
285 index.last_updated.store(
287 SystemTime::now()
288 .duration_since(UNIX_EPOCH)
289 .map_err(AgentError::SystemTimeError)?
290 .as_nanos() as u64,
291 Ordering::SeqCst,
292 );
293 index
294 .version
295 .store(index.version.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
296
297 Ok(())
298 }
299
300 pub async fn register_component(
302 &self,
303 component_id: String,
304 path: String,
305 ) -> Result<(), AgentError> {
306 let index = self.index.read().map_err(|_| {
307 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
308 })?;
309
310 index.component_paths.insert(
311 component_id,
312 (path.clone(), blake3::hash(path.as_bytes()).into()),
313 );
314
315 index.last_updated.store(
317 SystemTime::now()
318 .duration_since(UNIX_EPOCH)
319 .map_err(AgentError::SystemTimeError)?
320 .as_nanos() as u64,
321 Ordering::SeqCst,
322 );
323 index
324 .version
325 .store(index.version.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
326
327 Ok(())
328 }
329
330 pub async fn register_model(&self, model_id: String, path: String) -> Result<(), AgentError> {
332 let index = self.index.read().map_err(|_| {
333 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
334 })?;
335
336 let version_str = path.split('.').next_back().unwrap_or("0.0.0");
338 let version =
339 semver::Version::parse(version_str).unwrap_or_else(|_| semver::Version::new(0, 0, 0));
340
341 index.model_paths.insert(model_id, version);
342
343 index.last_updated.store(
345 SystemTime::now()
346 .duration_since(UNIX_EPOCH)
347 .map_err(AgentError::SystemTimeError)?
348 .as_nanos() as u64,
349 Ordering::SeqCst,
350 );
351 index
352 .version
353 .store(index.version.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
354
355 Ok(())
356 }
357
358 pub async fn crawl_and_update(&self) -> Result<(), AgentError> {
360 let update_data: HashMap<String, (String, [u8; 32])> = WalkDir::new(".")
361 .into_iter()
362 .filter_map(|e| e.ok())
363 .par_bridge()
364 .map(|entry| {
365 let path = entry.path().to_string_lossy().into_owned();
366 let hash = if entry.file_type().is_file() {
367 let data = std::fs::read(&path).unwrap_or_default();
368 blake3::hash(&data).to_hex().to_string()
369 } else {
370 String::new()
371 };
372
373 let file_type = if path.ends_with(".md") {
374 "Documentation"
375 } else if path.ends_with(".rs") {
376 "Rust Source"
377 } else {
378 "Asset"
379 };
380
381 let hash_bytes: [u8; 32] = blake3::hash(hash.as_bytes()).into();
382 (path, (file_type.to_string(), hash_bytes))
383 })
384 .collect();
385
386 {
388 let index = self.index.write().map_err(|_| {
389 AgentError::InternalError(
390 "Failed to acquire write lock on system index".to_string(),
391 )
392 })?;
393
394 for (path, (file_type, hash)) in update_data {
395 index.component_paths.insert(path, (file_type, hash));
396 }
397
398 index.last_updated.store(
399 SystemTime::now()
400 .duration_since(UNIX_EPOCH)
401 .map_err(AgentError::SystemTimeError)?
402 .as_nanos() as u64,
403 Ordering::SeqCst,
404 );
405 }
406
407 Ok(())
408 }
409
410 fn analyze_rust_file(&self, path: &str) -> RustCodeMetrics {
411 let content = std::fs::read_to_string(path).unwrap_or_default();
412 if let Ok(syntax) = syn::parse_file(&content) {
413 let mut metrics = RustCodeMetrics {
414 cyclomatic_complexity: calculate_cyclomatic_complexity(&syntax),
415 unsafe_usage_count: count_unsafe_blocks(&syntax),
416 test_coverage: get_test_coverage(path),
417 dependency_graph: analyze_dependencies(&content),
418 clippy_lints: run_clippy_checks(path),
419 security_audit_flags: check_bitcoin_security(&content),
420 bitcoin_protocol_adherence: calculate_protocol_adherence(&content),
421 };
422
423 if metrics.bitcoin_protocol_adherence < 0.9 {
425 metrics
426 .security_audit_flags
427 .push("Low Bitcoin protocol adherence - review BIP-341/342 compliance".into());
428 }
429
430 metrics
431 } else {
432 RustCodeMetrics::default()
433 }
434 }
435 pub fn enhanced_crawl(&self) -> Result<(), AgentError> {
436 let index = self.index.read().map_err(|_| {
437 AgentError::InternalError("Failed to acquire read lock on system index".to_string())
438 })?;
439
440 let walker = WalkDir::new(".")
441 .into_iter()
442 .filter_map(|e| e.ok())
443 .par_bridge()
444 .filter(|e| e.path().extension().map(|ext| ext == "rs").unwrap_or(false))
445 .map(|entry| {
446 let path = entry.path().to_string_lossy().into_owned();
447 let metrics = self.analyze_rust_file(&path);
448 (path, metrics)
449 });
450
451 walker.for_each(|(path, metrics)| {
452 index.rust_metrics.insert(path, metrics);
453 });
454
455 Ok(())
456 }
457
458 pub async fn bitcoin_health_check(&self) -> Result<f32, AgentError> {
459 let index = self.get_index_for_reading().await?;
460 let total = index.component_paths.len() as f32;
461 let compliant = index
462 .component_paths
463 .iter()
464 .filter(|entry| Self::is_bitcoin_related(std::path::Path::new(entry.key())))
465 .filter(|entry| entry.value().1.len() == 32) .count() as f32;
467
468 Ok(compliant / total.max(1.0))
469 }
470
471 pub fn is_bitcoin_related(path: &std::path::Path) -> bool {
473 let path_str = path.to_string_lossy().to_lowercase();
474 path_str.contains("bitcoin")
475 || path_str.contains("bip")
476 || path_str.contains("address")
477 || path_str.contains("transaction")
478 || path_str.contains("wallet")
479 || path_str.contains("script")
480 || path_str.contains("secp256k1")
481 || path_str.contains("hash")
482 || path_str.contains("merkle")
483 || path_str.contains("block")
484 }
485}
486
487pub struct SystemMapManager {
489 map: RwLock<SystemMap>,
490}
491
492impl Default for SystemMapManager {
493 fn default() -> Self {
494 Self::new()
495 }
496}
497
498impl SystemMapManager {
499 pub fn new() -> Self {
501 Self {
502 map: RwLock::new(SystemMap::default()),
503 }
504 }
505
506 pub async fn read_map(&self) -> Result<(), AgentError> {
508 let _map = self.map.read().map_err(|_| {
509 AgentError::InternalError("Failed to acquire read lock on system map".to_string())
510 })?;
511 Ok(())
512 }
513
514 pub async fn update_map(&self) -> Result<(), AgentError> {
516 let mut map = self.map.write().map_err(|_| {
517 AgentError::InternalError("Failed to acquire write lock on system map".to_string())
518 })?;
519
520 map.last_updated = std::time::SystemTime::now()
522 .duration_since(std::time::UNIX_EPOCH)
523 .unwrap_or_default()
524 .as_secs();
525
526 map.version += 1;
528
529 Ok(())
532 }
533
534 pub async fn update_component_state(
536 &self,
537 component_id: String,
538 state: ComponentState,
539 ) -> Result<(), AgentError> {
540 let mut map = self.map.write().map_err(|_| {
541 AgentError::InternalError("Failed to acquire write lock on system map".to_string())
542 })?;
543
544 map.component_states.insert(component_id, state);
545
546 map.last_updated = std::time::SystemTime::now()
548 .duration_since(std::time::UNIX_EPOCH)
549 .unwrap_or_default()
550 .as_secs();
551 map.version += 1;
552
553 Ok(())
554 }
555
556 pub async fn update_model_state(
558 &self,
559 model_id: String,
560 state: ModelState,
561 ) -> Result<(), AgentError> {
562 let mut map = self.map.write().map_err(|_| {
563 AgentError::InternalError("Failed to acquire write lock on system map".to_string())
564 })?;
565
566 map.model_states.insert(model_id, state);
567
568 map.last_updated = std::time::SystemTime::now()
570 .duration_since(std::time::UNIX_EPOCH)
571 .unwrap_or_default()
572 .as_secs();
573 map.version += 1;
574
575 Ok(())
576 }
577
578 pub async fn update_agent_relationships(
580 &self,
581 agent_id: String,
582 relationships: Vec<String>,
583 ) -> Result<(), AgentError> {
584 let mut map = self.map.write().map_err(|_| {
585 AgentError::InternalError("Failed to acquire write lock on system map".to_string())
586 })?;
587
588 map.agent_relationships.insert(agent_id, relationships);
589
590 map.last_updated = std::time::SystemTime::now()
592 .duration_since(std::time::UNIX_EPOCH)
593 .unwrap_or_default()
594 .as_secs();
595 map.version += 1;
596
597 Ok(())
598 }
599
600 pub async fn update_health_metrics(
602 &self,
603 metrics: HashMap<String, f64>,
604 ) -> Result<(), AgentError> {
605 let mut map = self.map.write().map_err(|_| {
606 AgentError::InternalError("Failed to acquire write lock on system map".to_string())
607 })?;
608
609 for (key, value) in metrics {
611 map.health_metrics.insert(key, value);
612 }
613
614 map.last_updated = std::time::SystemTime::now()
616 .duration_since(std::time::UNIX_EPOCH)
617 .unwrap_or_default()
618 .as_secs();
619 map.version += 1;
620
621 Ok(())
622 }
623}
624
625pub fn system_index() -> Arc<SystemIndexManager> {
627 GLOBAL_INDEX.clone()
628}
629
630pub fn system_map() -> Arc<SystemMapManager> {
632 GLOBAL_MAP.clone()
633}
634
635#[async_trait]
637pub trait IndexProvider {
638 fn global() -> Arc<SystemIndexManager>;
640
641 async fn read_index(&self) -> Result<(), AgentError>;
643
644 async fn increment_version(&self) -> Result<(), AgentError>;
646}
647
648#[async_trait]
650pub trait MapProvider {
651 fn global() -> Arc<SystemMapManager>;
653
654 async fn read_map(&self) -> Result<(), AgentError>;
656
657 async fn update_map(&self) -> Result<(), AgentError>;
659}
660
661#[async_trait]
662impl IndexProvider for SystemIndexManager {
663 fn global() -> Arc<SystemIndexManager> {
664 GLOBAL_INDEX.clone()
665 }
666
667 async fn read_index(&self) -> Result<(), AgentError> {
668 self.read_index().await
669 }
670
671 async fn increment_version(&self) -> Result<(), AgentError> {
672 self.increment_version().await
673 }
674}
675
676#[async_trait]
677impl MapProvider for SystemMapManager {
678 fn global() -> Arc<SystemMapManager> {
679 GLOBAL_MAP.clone()
680 }
681
682 async fn read_map(&self) -> Result<(), AgentError> {
683 self.read_map().await
684 }
685
686 async fn update_map(&self) -> Result<(), AgentError> {
687 self.update_map().await
688 }
689}
690
691fn calculate_cyclomatic_complexity(_syntax: &syn::File) -> f32 {
693 1.0 }
695fn count_unsafe_blocks(_syntax: &syn::File) -> u32 {
696 0
697}
698fn get_test_coverage(_path: &str) -> f32 {
699 0.0
700}
701fn analyze_dependencies(_content: &str) -> HashMap<String, Vec<String>> {
702 HashMap::new()
703}
704fn run_clippy_checks(_path: &str) -> HashMap<String, u32> {
705 HashMap::new()
706}
707fn check_bitcoin_security(_content: &str) -> Vec<String> {
708 vec![]
709}
710fn calculate_protocol_adherence(_content: &str) -> f32 {
711 0.0
712}
713
714#[cfg(test)]
715mod tests {
716
717 #[tokio::test]
718 async fn test_system_index_operations() {
719 }
721
722 #[tokio::test]
723 async fn test_system_map_operations() {
724 }
726}