1use crate::{
31 adaptive_polling::{AdaptivePolling, AdaptivePollingConfig},
32 background_mode::{BackgroundModeConfig, BackgroundModeManager},
33 dht::{DhtConfig, DhtManager},
34 dht_provider::{kademlia::KademliaDhtProvider, DhtProviderRegistry},
35 geo_routing::{GeoRouter, GeoRouterConfig},
36 gossipsub::{GossipSubConfig, GossipSubManager},
37 memory_monitor::{MemoryMonitor, MemoryMonitorConfig},
38 multipath_quic::{MultipathConfig, MultipathQuicManager},
39 network_monitor::{NetworkMonitor, NetworkMonitorConfig},
40 node::{NetworkConfig, NetworkHealthSummary, NetworkNode},
41 offline_queue::{OfflineQueue, OfflineQueueConfig},
42 peer::{PeerStore, PeerStoreConfig},
43 peer_selector::{PeerSelector, PeerSelectorConfig},
44 presets::NetworkPreset,
45 quality_predictor::{QualityPredictor, QualityPredictorConfig},
46 query_batcher::{QueryBatcher, QueryBatcherConfig},
47 semantic_dht::{SemanticDht, SemanticDhtConfig},
48 throttle::{BandwidthThrottle, ThrottleConfig},
49 tor::{TorConfig, TorManager},
50};
51use libp2p::{Multiaddr, PeerId};
52use parking_lot::RwLock;
53use std::sync::Arc;
54use tokio::sync::RwLock as AsyncRwLock;
55
56type IpfrsResult<T> = ipfrs_core::error::Result<T>;
57
58#[derive(Debug, Clone)]
60pub struct NetworkStats {
61 pub peer_count: usize,
62 pub bytes_sent: u64,
63 pub bytes_received: u64,
64 pub is_healthy: bool,
65 pub semantic_dht_enabled: bool,
66 pub gossipsub_enabled: bool,
67 pub geo_routing_enabled: bool,
68 pub tor_enabled: bool,
69 pub bandwidth_throttle_enabled: bool,
70 pub memory_monitor_enabled: bool,
71}
72
73#[derive(Debug, Clone)]
75pub struct ModuleStatus {
76 pub semantic_dht: bool,
77 pub gossipsub: bool,
78 pub geo_routing: bool,
79 pub quality_predictor: bool,
80 pub peer_selector: bool,
81 pub multipath_quic: bool,
82 pub tor: bool,
83 pub bandwidth_throttle: bool,
84 pub adaptive_polling: bool,
85 pub background_mode: bool,
86 pub offline_queue: bool,
87 pub memory_monitor: bool,
88 pub network_monitor: bool,
89 pub query_batcher: bool,
90}
91
92pub struct NetworkFacade {
94 pub node: NetworkNode,
96
97 pub semantic_dht: Option<Arc<RwLock<SemanticDht>>>,
99 pub gossipsub: Option<Arc<RwLock<GossipSubManager>>>,
100 pub geo_router: Option<Arc<RwLock<GeoRouter>>>,
101 pub quality_predictor: Option<Arc<RwLock<QualityPredictor>>>,
102 pub peer_selector: Option<Arc<RwLock<PeerSelector>>>,
103 pub multipath_quic: Option<Arc<RwLock<MultipathQuicManager>>>,
104 pub tor_manager: Option<Arc<AsyncRwLock<TorManager>>>,
105 pub bandwidth_throttle: Option<Arc<RwLock<BandwidthThrottle>>>,
106 pub adaptive_polling: Option<Arc<RwLock<AdaptivePolling>>>,
107 pub background_mode: Option<Arc<RwLock<BackgroundModeManager>>>,
108 pub offline_queue: Option<Arc<RwLock<OfflineQueue>>>,
109 pub memory_monitor: Option<Arc<RwLock<MemoryMonitor>>>,
110 pub network_monitor: Option<Arc<RwLock<NetworkMonitor>>>,
111 pub query_batcher: Option<Arc<RwLock<QueryBatcher>>>,
112
113 pub peer_store: Arc<RwLock<PeerStore>>,
115 pub dht_manager: Arc<RwLock<DhtManager>>,
116 pub dht_provider_registry: Arc<RwLock<DhtProviderRegistry>>,
117}
118
119impl NetworkFacade {
120 pub fn new(config: NetworkConfig) -> IpfrsResult<Self> {
122 let node = NetworkNode::new(config)?;
123 let peer_store = Arc::new(RwLock::new(PeerStore::with_config(
124 PeerStoreConfig::default(),
125 )));
126 let dht_manager = Arc::new(RwLock::new(DhtManager::new(DhtConfig::default())));
127 let dht_provider_registry = Arc::new(RwLock::new(DhtProviderRegistry::new()));
128
129 Ok(Self {
130 node,
131 semantic_dht: None,
132 gossipsub: None,
133 geo_router: None,
134 quality_predictor: None,
135 peer_selector: None,
136 multipath_quic: None,
137 tor_manager: None,
138 bandwidth_throttle: None,
139 adaptive_polling: None,
140 background_mode: None,
141 offline_queue: None,
142 memory_monitor: None,
143 network_monitor: None,
144 query_batcher: None,
145 peer_store,
146 dht_manager,
147 dht_provider_registry,
148 })
149 }
150
151 pub async fn start(&mut self) -> IpfrsResult<()> {
153 self.node.start().await?;
154
155 if let Some(tor) = &self.tor_manager {
157 tor.write().await.start().await.map_err(|e| {
158 ipfrs_core::error::Error::Network(format!("Failed to start Tor: {}", e))
159 })?;
160 }
161
162 Ok(())
163 }
164
165 pub async fn stop(&mut self) -> IpfrsResult<()> {
167 if let Some(tor) = &self.tor_manager {
169 tor.write().await.stop().await.map_err(|e| {
170 ipfrs_core::error::Error::Network(format!("Failed to stop Tor: {}", e))
171 })?;
172 }
173
174 self.node.stop().await
175 }
176
177 pub fn peer_id(&self) -> PeerId {
179 self.node.peer_id()
180 }
181
182 pub fn connected_peers(&self) -> Vec<PeerId> {
184 self.node.connected_peers()
185 }
186
187 pub async fn connect(&mut self, addr: Multiaddr) -> IpfrsResult<()> {
189 self.node.connect(addr).await
190 }
191
192 pub async fn disconnect(&mut self, peer_id: PeerId) -> IpfrsResult<()> {
194 self.node.disconnect(peer_id).await
195 }
196
197 pub async fn provide(&mut self, cid: &cid::Cid) -> IpfrsResult<()> {
199 self.node.provide(cid).await
200 }
201
202 pub async fn find_providers(&mut self, cid: &cid::Cid) -> IpfrsResult<()> {
204 self.node.find_providers(cid).await
205 }
206
207 pub fn get_health(&self) -> NetworkHealthSummary {
209 self.node.get_network_health()
210 }
211
212 pub fn is_healthy(&self) -> bool {
214 self.node.is_healthy()
215 }
216
217 pub fn peer_count(&self) -> usize {
219 self.node.get_peer_count()
220 }
221
222 pub fn is_connected_to(&self, peer_id: &PeerId) -> bool {
224 self.node.is_connected_to(peer_id)
225 }
226
227 pub fn bytes_sent(&self) -> u64 {
229 self.node.get_bytes_sent()
230 }
231
232 pub fn bytes_received(&self) -> u64 {
234 self.node.get_bytes_received()
235 }
236
237 pub async fn with_tor_manager(
239 &mut self,
240 config: TorConfig,
241 ) -> Result<(), crate::tor::TorError> {
242 let manager = TorManager::new(config).await?;
243 self.tor_manager = Some(Arc::new(AsyncRwLock::new(manager)));
244 Ok(())
245 }
246
247 pub fn semantic_search(
256 &self,
257 namespace: &crate::semantic_dht::NamespaceId,
258 embedding: Vec<f32>,
259 top_k: usize,
260 ) -> IpfrsResult<Vec<crate::semantic_dht::SemanticResult>> {
261 let dht = self.semantic_dht.as_ref().ok_or_else(|| {
262 ipfrs_core::error::Error::Network("Semantic DHT not enabled".to_string())
263 })?;
264
265 let query = crate::semantic_dht::SemanticQuery {
266 embedding,
267 namespace: namespace.clone(),
268 top_k,
269 metadata_filter: None,
270 timeout: std::time::Duration::from_secs(30),
271 };
272
273 dht.read().query(query).map_err(|e| {
274 ipfrs_core::error::Error::Network(format!("Semantic search failed: {}", e))
275 })
276 }
277
278 pub fn index_content(
280 &self,
281 cid: cid::Cid,
282 embedding: Vec<f32>,
283 namespace: crate::semantic_dht::NamespaceId,
284 ) -> IpfrsResult<()> {
285 let dht = self.semantic_dht.as_ref().ok_or_else(|| {
286 ipfrs_core::error::Error::Network("Semantic DHT not enabled".to_string())
287 })?;
288
289 dht.write()
290 .index_content(cid, embedding, namespace)
291 .map_err(|e| {
292 ipfrs_core::error::Error::Network(format!("Semantic indexing failed: {}", e))
293 })
294 }
295
296 pub fn register_semantic_namespace(
298 &self,
299 namespace: crate::semantic_dht::NamespaceId,
300 dimension: usize,
301 ) -> IpfrsResult<()> {
302 let dht = self.semantic_dht.as_ref().ok_or_else(|| {
303 ipfrs_core::error::Error::Network("Semantic DHT not enabled".to_string())
304 })?;
305
306 let ns = crate::semantic_dht::SemanticNamespace {
307 id: namespace,
308 dimension,
309 distance_metric: crate::semantic_dht::DistanceMetric::Cosine,
310 lsh_config: Default::default(),
311 };
312
313 dht.write().register_namespace(ns).map_err(|e| {
314 ipfrs_core::error::Error::Network(format!("Namespace registration failed: {}", e))
315 })
316 }
317
318 pub fn subscribe(&self, topic: &str) -> IpfrsResult<()> {
324 let gossipsub = self.gossipsub.as_ref().ok_or_else(|| {
325 ipfrs_core::error::Error::Network("GossipSub not enabled".to_string())
326 })?;
327
328 let topic_id = crate::gossipsub::TopicId::new(topic);
329 gossipsub
330 .write()
331 .subscribe(topic_id)
332 .map_err(|e| ipfrs_core::error::Error::Network(format!("Subscribe failed: {}", e)))
333 }
334
335 pub fn unsubscribe(&self, topic: &str) -> IpfrsResult<()> {
337 let gossipsub = self.gossipsub.as_ref().ok_or_else(|| {
338 ipfrs_core::error::Error::Network("GossipSub not enabled".to_string())
339 })?;
340
341 let topic_id = crate::gossipsub::TopicId::new(topic);
342 gossipsub
343 .write()
344 .unsubscribe(&topic_id)
345 .map_err(|e| ipfrs_core::error::Error::Network(format!("Unsubscribe failed: {}", e)))
346 }
347
348 pub fn publish(&self, topic: &str, data: Vec<u8>) -> IpfrsResult<crate::gossipsub::MessageId> {
350 let gossipsub = self.gossipsub.as_ref().ok_or_else(|| {
351 ipfrs_core::error::Error::Network("GossipSub not enabled".to_string())
352 })?;
353
354 let topic_id = crate::gossipsub::TopicId::new(topic);
355 let source = self.peer_id();
356 gossipsub
357 .write()
358 .publish(topic_id, data, source)
359 .map_err(|e| ipfrs_core::error::Error::Network(format!("Publish failed: {}", e)))
360 }
361
362 pub fn subscribed_topics(&self) -> IpfrsResult<Vec<String>> {
364 let _gossipsub = self.gossipsub.as_ref().ok_or_else(|| {
365 ipfrs_core::error::Error::Network("GossipSub not enabled".to_string())
366 })?;
367
368 Ok(Vec::new())
371 }
372
373 pub fn find_nearby_peers(
379 &self,
380 location: crate::geo_routing::GeoLocation,
381 ) -> IpfrsResult<Vec<PeerId>> {
382 let geo_router = self.geo_router.as_ref().ok_or_else(|| {
383 ipfrs_core::error::Error::Network("Geographic routing not enabled".to_string())
384 })?;
385
386 Ok(geo_router
387 .read()
388 .get_nearby_peers(&location)
389 .iter()
390 .map(|p| p.peer_id)
391 .collect())
392 }
393
394 pub fn set_peer_location(
396 &self,
397 peer_id: PeerId,
398 location: crate::geo_routing::GeoLocation,
399 ) -> IpfrsResult<()> {
400 let geo_router = self.geo_router.as_ref().ok_or_else(|| {
401 ipfrs_core::error::Error::Network("Geographic routing not enabled".to_string())
402 })?;
403
404 geo_router.read().update_peer_location(peer_id, location);
405 Ok(())
406 }
407
408 pub fn get_best_peers(&self, peers: &[PeerId], count: usize) -> IpfrsResult<Vec<PeerId>> {
410 let predictor = self.quality_predictor.as_ref().ok_or_else(|| {
411 ipfrs_core::error::Error::Network("Quality predictor not enabled".to_string())
412 })?;
413
414 Ok(predictor
415 .read()
416 .rank_peers(peers)
417 .into_iter()
418 .take(count)
419 .map(|(peer_id, _)| peer_id)
420 .collect())
421 }
422
423 pub fn select_optimal_peers(
425 &self,
426 criteria: &crate::peer_selector::SelectionCriteria,
427 ) -> IpfrsResult<Vec<PeerId>> {
428 let selector = self.peer_selector.as_ref().ok_or_else(|| {
429 ipfrs_core::error::Error::Network("Peer selector not enabled".to_string())
430 })?;
431
432 Ok(selector
433 .read()
434 .select_peers(criteria)
435 .into_iter()
436 .map(|p| p.peer_id)
437 .collect())
438 }
439
440 pub fn get_network_stats(&self) -> NetworkStats {
446 NetworkStats {
447 peer_count: self.peer_count(),
448 bytes_sent: self.bytes_sent(),
449 bytes_received: self.bytes_received(),
450 is_healthy: self.is_healthy(),
451 semantic_dht_enabled: self.semantic_dht.is_some(),
452 gossipsub_enabled: self.gossipsub.is_some(),
453 geo_routing_enabled: self.geo_router.is_some(),
454 tor_enabled: self.tor_manager.is_some(),
455 bandwidth_throttle_enabled: self.bandwidth_throttle.is_some(),
456 memory_monitor_enabled: self.memory_monitor.is_some(),
457 }
458 }
459
460 pub fn get_module_status(&self) -> ModuleStatus {
462 ModuleStatus {
463 semantic_dht: self.semantic_dht.is_some(),
464 gossipsub: self.gossipsub.is_some(),
465 geo_routing: self.geo_router.is_some(),
466 quality_predictor: self.quality_predictor.is_some(),
467 peer_selector: self.peer_selector.is_some(),
468 multipath_quic: self.multipath_quic.is_some(),
469 tor: self.tor_manager.is_some(),
470 bandwidth_throttle: self.bandwidth_throttle.is_some(),
471 adaptive_polling: self.adaptive_polling.is_some(),
472 background_mode: self.background_mode.is_some(),
473 offline_queue: self.offline_queue.is_some(),
474 memory_monitor: self.memory_monitor.is_some(),
475 network_monitor: self.network_monitor.is_some(),
476 query_batcher: self.query_batcher.is_some(),
477 }
478 }
479
480 pub fn get_memory_stats(&self) -> IpfrsResult<crate::memory_monitor::MemoryStats> {
482 let monitor = self.memory_monitor.as_ref().ok_or_else(|| {
483 ipfrs_core::error::Error::Network("Memory monitor not enabled".to_string())
484 })?;
485
486 Ok(monitor.read().stats())
487 }
488
489 pub async fn connect_batch(&mut self, addrs: Vec<Multiaddr>) -> Vec<IpfrsResult<()>> {
495 self.node.connect_to_peers(addrs).await
496 }
497
498 pub async fn provide_batch(&mut self, cids: Vec<cid::Cid>) -> Vec<IpfrsResult<()>> {
500 let mut results = Vec::new();
501 for cid in cids {
502 results.push(self.provide(&cid).await);
503 }
504 results
505 }
506
507 pub async fn find_providers_batch(&mut self, cids: Vec<cid::Cid>) -> Vec<IpfrsResult<()>> {
509 let mut results = Vec::new();
510 for cid in cids {
511 results.push(self.find_providers(&cid).await);
512 }
513 results
514 }
515
516 pub fn is_module_enabled(&self, module: &str) -> bool {
522 match module {
523 "semantic_dht" => self.semantic_dht.is_some(),
524 "gossipsub" => self.gossipsub.is_some(),
525 "geo_routing" => self.geo_router.is_some(),
526 "quality_predictor" => self.quality_predictor.is_some(),
527 "peer_selector" => self.peer_selector.is_some(),
528 "multipath_quic" => self.multipath_quic.is_some(),
529 "tor" => self.tor_manager.is_some(),
530 "bandwidth_throttle" => self.bandwidth_throttle.is_some(),
531 "adaptive_polling" => self.adaptive_polling.is_some(),
532 "background_mode" => self.background_mode.is_some(),
533 "offline_queue" => self.offline_queue.is_some(),
534 "memory_monitor" => self.memory_monitor.is_some(),
535 "network_monitor" => self.network_monitor.is_some(),
536 "query_batcher" => self.query_batcher.is_some(),
537 _ => false,
538 }
539 }
540
541 pub fn enabled_modules(&self) -> Vec<String> {
543 let modules = vec![
544 ("semantic_dht", self.semantic_dht.is_some()),
545 ("gossipsub", self.gossipsub.is_some()),
546 ("geo_routing", self.geo_router.is_some()),
547 ("quality_predictor", self.quality_predictor.is_some()),
548 ("peer_selector", self.peer_selector.is_some()),
549 ("multipath_quic", self.multipath_quic.is_some()),
550 ("tor", self.tor_manager.is_some()),
551 ("bandwidth_throttle", self.bandwidth_throttle.is_some()),
552 ("adaptive_polling", self.adaptive_polling.is_some()),
553 ("background_mode", self.background_mode.is_some()),
554 ("offline_queue", self.offline_queue.is_some()),
555 ("memory_monitor", self.memory_monitor.is_some()),
556 ("network_monitor", self.network_monitor.is_some()),
557 ("query_batcher", self.query_batcher.is_some()),
558 ];
559
560 modules
561 .into_iter()
562 .filter_map(|(name, enabled)| {
563 if enabled {
564 Some(name.to_string())
565 } else {
566 None
567 }
568 })
569 .collect()
570 }
571
572 pub fn summary(&self) -> String {
574 let enabled = self.enabled_modules();
575 format!(
576 "NetworkFacade {{\n Peer ID: {}\n Peers: {}\n Health: {:?}\n Enabled modules ({}):\n {}\n}}",
577 self.peer_id(),
578 self.peer_count(),
579 self.get_health().status,
580 enabled.len(),
581 enabled.join(", ")
582 )
583 }
584}
585
586pub struct NetworkFacadeBuilder {
588 config: NetworkConfig,
589 enable_semantic_dht: bool,
590 enable_gossipsub: bool,
591 enable_geo_routing: bool,
592 enable_quality_predictor: bool,
593 enable_peer_selector: bool,
594 enable_multipath_quic: bool,
595 enable_tor: bool,
596 enable_bandwidth_throttle: bool,
597 enable_adaptive_polling: bool,
598 enable_background_mode: bool,
599 enable_offline_queue: bool,
600 enable_memory_monitor: bool,
601 enable_network_monitor: bool,
602 enable_query_batcher: bool,
603
604 semantic_dht_config: Option<SemanticDhtConfig>,
605 gossipsub_config: Option<GossipSubConfig>,
606 geo_router_config: Option<GeoRouterConfig>,
607 quality_predictor_config: Option<QualityPredictorConfig>,
608 peer_selector_config: Option<PeerSelectorConfig>,
609 multipath_config: Option<MultipathConfig>,
610 tor_config: Option<TorConfig>,
611 throttle_config: Option<ThrottleConfig>,
612 adaptive_polling_config: Option<AdaptivePollingConfig>,
613 background_mode_config: Option<BackgroundModeConfig>,
614 offline_queue_config: Option<OfflineQueueConfig>,
615 memory_monitor_config: Option<MemoryMonitorConfig>,
616 network_monitor_config: Option<NetworkMonitorConfig>,
617 query_batcher_config: Option<QueryBatcherConfig>,
618 peer_store_config: Option<PeerStoreConfig>,
619 dht_config: Option<DhtConfig>,
620}
621
622impl NetworkFacadeBuilder {
623 pub fn new() -> Self {
625 Self {
626 config: NetworkConfig::default(),
627 enable_semantic_dht: false,
628 enable_gossipsub: false,
629 enable_geo_routing: false,
630 enable_quality_predictor: false,
631 enable_peer_selector: false,
632 enable_multipath_quic: false,
633 enable_tor: false,
634 enable_bandwidth_throttle: false,
635 enable_adaptive_polling: false,
636 enable_background_mode: false,
637 enable_offline_queue: false,
638 enable_memory_monitor: false,
639 enable_network_monitor: false,
640 enable_query_batcher: false,
641 semantic_dht_config: None,
642 gossipsub_config: None,
643 geo_router_config: None,
644 quality_predictor_config: None,
645 peer_selector_config: None,
646 multipath_config: None,
647 tor_config: None,
648 throttle_config: None,
649 adaptive_polling_config: None,
650 background_mode_config: None,
651 offline_queue_config: None,
652 memory_monitor_config: None,
653 network_monitor_config: None,
654 query_batcher_config: None,
655 peer_store_config: None,
656 dht_config: None,
657 }
658 }
659
660 pub fn with_preset(mut self, preset: NetworkPreset) -> Self {
662 self.config = preset.network;
663
664 if let Some(config) = preset.throttle {
665 self.throttle_config = Some(config);
666 self.enable_bandwidth_throttle = true;
667 }
668
669 if let Some(config) = preset.adaptive_polling {
670 self.adaptive_polling_config = Some(config);
671 self.enable_adaptive_polling = true;
672 }
673
674 if let Some(config) = preset.memory_monitor {
675 self.memory_monitor_config = Some(config);
676 self.enable_memory_monitor = true;
677 }
678
679 if let Some(config) = preset.offline_queue {
680 self.offline_queue_config = Some(config);
681 self.enable_offline_queue = true;
682 }
683
684 if let Some(config) = preset.background_mode {
685 self.background_mode_config = Some(config);
686 self.enable_background_mode = true;
687 }
688
689 if let Some(config) = preset.query_batcher {
690 self.query_batcher_config = Some(config);
691 self.enable_query_batcher = true;
692 }
693
694 if let Some(config) = preset.geo_router {
695 self.geo_router_config = Some(config);
696 self.enable_geo_routing = true;
697 }
698
699 if let Some(config) = preset.quality_predictor {
700 self.quality_predictor_config = Some(config);
701 self.enable_quality_predictor = true;
702 }
703
704 if let Some(config) = preset.peer_selector {
705 self.peer_selector_config = Some(config);
706 self.enable_peer_selector = true;
707 }
708
709 if let Some(config) = preset.multipath {
710 self.multipath_config = Some(config);
711 self.enable_multipath_quic = true;
712 }
713
714 if let Some(config) = preset.tor {
715 self.tor_config = Some(config);
716 self.enable_tor = true;
717 }
718
719 self.peer_store_config = Some(preset.peer_store);
720 self.dht_config = Some(preset.dht);
721
722 self
723 }
724
725 pub fn with_preset_mobile(self) -> Self {
727 self.with_preset(NetworkPreset::mobile())
728 }
729
730 pub fn with_preset_iot(self) -> Self {
732 self.with_preset(NetworkPreset::iot())
733 }
734
735 pub fn with_preset_low_memory(self) -> Self {
737 self.with_preset(NetworkPreset::low_memory())
738 }
739
740 pub fn with_preset_high_performance(self) -> Self {
742 self.with_preset(NetworkPreset::high_performance())
743 }
744
745 pub fn with_preset_privacy(self) -> Self {
747 self.with_preset(NetworkPreset::privacy())
748 }
749
750 pub fn with_config(mut self, config: NetworkConfig) -> Self {
752 self.config = config;
753 self
754 }
755
756 pub fn with_semantic_dht(mut self) -> Self {
758 self.enable_semantic_dht = true;
759 self
760 }
761
762 pub fn with_semantic_dht_config(mut self, config: SemanticDhtConfig) -> Self {
764 self.enable_semantic_dht = true;
765 self.semantic_dht_config = Some(config);
766 self
767 }
768
769 pub fn with_gossipsub(mut self) -> Self {
771 self.enable_gossipsub = true;
772 self
773 }
774
775 pub fn with_gossipsub_config(mut self, config: GossipSubConfig) -> Self {
777 self.enable_gossipsub = true;
778 self.gossipsub_config = Some(config);
779 self
780 }
781
782 pub fn with_geo_routing(mut self) -> Self {
784 self.enable_geo_routing = true;
785 self
786 }
787
788 pub fn with_geo_routing_config(mut self, config: GeoRouterConfig) -> Self {
790 self.enable_geo_routing = true;
791 self.geo_router_config = Some(config);
792 self
793 }
794
795 pub fn with_quality_predictor(mut self) -> Self {
797 self.enable_quality_predictor = true;
798 self
799 }
800
801 pub fn with_quality_predictor_config(mut self, config: QualityPredictorConfig) -> Self {
803 self.enable_quality_predictor = true;
804 self.quality_predictor_config = Some(config);
805 self
806 }
807
808 pub fn with_peer_selector(mut self) -> Self {
810 self.enable_peer_selector = true;
811 self
812 }
813
814 pub fn with_peer_selector_config(mut self, config: PeerSelectorConfig) -> Self {
816 self.enable_peer_selector = true;
817 self.peer_selector_config = Some(config);
818 self
819 }
820
821 pub fn with_multipath_quic(mut self) -> Self {
823 self.enable_multipath_quic = true;
824 self
825 }
826
827 pub fn with_multipath_quic_config(mut self, config: MultipathConfig) -> Self {
829 self.enable_multipath_quic = true;
830 self.multipath_config = Some(config);
831 self
832 }
833
834 pub fn with_tor(mut self) -> Self {
836 self.enable_tor = true;
837 self
838 }
839
840 pub fn with_tor_config(mut self, config: TorConfig) -> Self {
842 self.enable_tor = true;
843 self.tor_config = Some(config);
844 self
845 }
846
847 pub fn with_bandwidth_throttle(mut self) -> Self {
849 self.enable_bandwidth_throttle = true;
850 self
851 }
852
853 pub fn with_bandwidth_throttle_config(mut self, config: ThrottleConfig) -> Self {
855 self.enable_bandwidth_throttle = true;
856 self.throttle_config = Some(config);
857 self
858 }
859
860 pub fn with_adaptive_polling(mut self) -> Self {
862 self.enable_adaptive_polling = true;
863 self
864 }
865
866 pub fn with_adaptive_polling_config(mut self, config: AdaptivePollingConfig) -> Self {
868 self.enable_adaptive_polling = true;
869 self.adaptive_polling_config = Some(config);
870 self
871 }
872
873 pub fn with_background_mode(mut self) -> Self {
875 self.enable_background_mode = true;
876 self
877 }
878
879 pub fn with_background_mode_config(mut self, config: BackgroundModeConfig) -> Self {
881 self.enable_background_mode = true;
882 self.background_mode_config = Some(config);
883 self
884 }
885
886 pub fn with_offline_queue(mut self) -> Self {
888 self.enable_offline_queue = true;
889 self
890 }
891
892 pub fn with_offline_queue_config(mut self, config: OfflineQueueConfig) -> Self {
894 self.enable_offline_queue = true;
895 self.offline_queue_config = Some(config);
896 self
897 }
898
899 pub fn with_memory_monitor(mut self) -> Self {
901 self.enable_memory_monitor = true;
902 self
903 }
904
905 pub fn with_memory_monitor_config(mut self, config: MemoryMonitorConfig) -> Self {
907 self.enable_memory_monitor = true;
908 self.memory_monitor_config = Some(config);
909 self
910 }
911
912 pub fn with_network_monitor(mut self) -> Self {
914 self.enable_network_monitor = true;
915 self
916 }
917
918 pub fn with_network_monitor_config(mut self, config: NetworkMonitorConfig) -> Self {
920 self.enable_network_monitor = true;
921 self.network_monitor_config = Some(config);
922 self
923 }
924
925 pub fn with_query_batcher(mut self) -> Self {
927 self.enable_query_batcher = true;
928 self
929 }
930
931 pub fn with_query_batcher_config(mut self, config: QueryBatcherConfig) -> Self {
933 self.enable_query_batcher = true;
934 self.query_batcher_config = Some(config);
935 self
936 }
937
938 pub fn build(self) -> IpfrsResult<NetworkFacade> {
940 let node = NetworkNode::new(self.config)?;
941
942 let peer_store = Arc::new(RwLock::new(if let Some(config) = self.peer_store_config {
943 PeerStore::with_config(config)
944 } else {
945 PeerStore::with_config(PeerStoreConfig::default())
946 }));
947
948 let dht_manager = Arc::new(RwLock::new(if let Some(config) = self.dht_config {
949 DhtManager::new(config)
950 } else {
951 DhtManager::new(DhtConfig::default())
952 }));
953
954 let dht_provider_registry = Arc::new(RwLock::new({
955 let mut registry = DhtProviderRegistry::new();
956 registry.register("kademlia", Arc::new(KademliaDhtProvider::new()));
957 registry
958 }));
959
960 Ok(NetworkFacade {
961 node,
962 semantic_dht: if self.enable_semantic_dht {
963 Some(Arc::new(RwLock::new(SemanticDht::new(
964 self.semantic_dht_config.unwrap_or_default(),
965 ))))
966 } else {
967 None
968 },
969 gossipsub: if self.enable_gossipsub {
970 Some(Arc::new(RwLock::new(GossipSubManager::new(
971 self.gossipsub_config.unwrap_or_default(),
972 ))))
973 } else {
974 None
975 },
976 geo_router: if self.enable_geo_routing {
977 Some(Arc::new(RwLock::new(GeoRouter::new(
978 self.geo_router_config.unwrap_or_default(),
979 ))))
980 } else {
981 None
982 },
983 quality_predictor: if self.enable_quality_predictor {
984 let config = self.quality_predictor_config.unwrap_or_default();
985 Some(Arc::new(RwLock::new(
986 QualityPredictor::new(config).map_err(|e| {
987 ipfrs_core::error::Error::Network(format!(
988 "Failed to create quality predictor: {}",
989 e
990 ))
991 })?,
992 )))
993 } else {
994 None
995 },
996 peer_selector: if self.enable_peer_selector {
997 Some(Arc::new(RwLock::new(PeerSelector::new(
998 self.peer_selector_config.unwrap_or_default(),
999 ))))
1000 } else {
1001 None
1002 },
1003 multipath_quic: if self.enable_multipath_quic {
1004 Some(Arc::new(RwLock::new(MultipathQuicManager::new(
1005 self.multipath_config.unwrap_or_default(),
1006 ))))
1007 } else {
1008 None
1009 },
1010 tor_manager: None,
1013 bandwidth_throttle: if self.enable_bandwidth_throttle {
1014 let config = self.throttle_config.unwrap_or_default();
1015 Some(Arc::new(RwLock::new(
1016 BandwidthThrottle::new(config).map_err(|e| {
1017 ipfrs_core::error::Error::Network(format!(
1018 "Failed to create bandwidth throttle: {}",
1019 e
1020 ))
1021 })?,
1022 )))
1023 } else {
1024 None
1025 },
1026 adaptive_polling: if self.enable_adaptive_polling {
1027 let config = self.adaptive_polling_config.unwrap_or_default();
1028 Some(Arc::new(RwLock::new(
1029 AdaptivePolling::new(config).map_err(|e| {
1030 ipfrs_core::error::Error::Network(format!(
1031 "Failed to create adaptive polling: {}",
1032 e
1033 ))
1034 })?,
1035 )))
1036 } else {
1037 None
1038 },
1039 background_mode: if self.enable_background_mode {
1040 Some(Arc::new(RwLock::new(BackgroundModeManager::new(
1041 self.background_mode_config.unwrap_or_default(),
1042 ))))
1043 } else {
1044 None
1045 },
1046 offline_queue: if self.enable_offline_queue {
1047 let config = self.offline_queue_config.unwrap_or_default();
1048 Some(Arc::new(RwLock::new(OfflineQueue::new(config).map_err(
1049 |e| {
1050 ipfrs_core::error::Error::Network(format!(
1051 "Failed to create offline queue: {}",
1052 e
1053 ))
1054 },
1055 )?)))
1056 } else {
1057 None
1058 },
1059 memory_monitor: if self.enable_memory_monitor {
1060 let config = self.memory_monitor_config.unwrap_or_default();
1061 Some(Arc::new(RwLock::new(MemoryMonitor::new(config).map_err(
1062 |e| {
1063 ipfrs_core::error::Error::Network(format!(
1064 "Failed to create memory monitor: {}",
1065 e
1066 ))
1067 },
1068 )?)))
1069 } else {
1070 None
1071 },
1072 network_monitor: if self.enable_network_monitor {
1073 let config = self.network_monitor_config.unwrap_or_default();
1074 Some(Arc::new(RwLock::new(NetworkMonitor::new(config))))
1075 } else {
1076 None
1077 },
1078 query_batcher: if self.enable_query_batcher {
1079 let config = self.query_batcher_config.unwrap_or_default();
1080 Some(Arc::new(RwLock::new(QueryBatcher::new(config).map_err(
1081 |e| {
1082 ipfrs_core::error::Error::Network(format!(
1083 "Failed to create query batcher: {}",
1084 e
1085 ))
1086 },
1087 )?)))
1088 } else {
1089 None
1090 },
1091 peer_store,
1092 dht_manager,
1093 dht_provider_registry,
1094 })
1095 }
1096}
1097
1098impl Default for NetworkFacadeBuilder {
1099 fn default() -> Self {
1100 Self::new()
1101 }
1102}
1103
1104#[cfg(test)]
1105mod tests {
1106 use super::*;
1107
1108 #[test]
1109 fn test_builder_default() {
1110 let builder = NetworkFacadeBuilder::new();
1111 assert!(!builder.enable_semantic_dht);
1112 assert!(!builder.enable_gossipsub);
1113 }
1114
1115 #[test]
1116 fn test_builder_with_features() {
1117 let builder = NetworkFacadeBuilder::new()
1118 .with_semantic_dht()
1119 .with_gossipsub()
1120 .with_geo_routing();
1121
1122 assert!(builder.enable_semantic_dht);
1123 assert!(builder.enable_gossipsub);
1124 assert!(builder.enable_geo_routing);
1125 }
1126
1127 #[test]
1128 fn test_builder_with_mobile_preset() {
1129 let builder = NetworkFacadeBuilder::new().with_preset_mobile();
1130 assert!(builder.enable_bandwidth_throttle);
1131 assert!(builder.enable_adaptive_polling);
1132 }
1133
1134 #[test]
1135 fn test_builder_with_iot_preset() {
1136 let builder = NetworkFacadeBuilder::new().with_preset_iot();
1137 assert!(builder.enable_bandwidth_throttle);
1138 assert!(builder.enable_query_batcher);
1139 }
1140
1141 #[test]
1142 fn test_builder_with_privacy_preset() {
1143 let builder = NetworkFacadeBuilder::new().with_preset_privacy();
1144 assert!(builder.enable_tor);
1145 }
1146
1147 #[tokio::test]
1148 async fn test_facade_creation() {
1149 let result = NetworkFacadeBuilder::new().build();
1150 assert!(result.is_ok());
1151
1152 let facade = result.unwrap();
1153 assert!(facade.semantic_dht.is_none());
1154 assert!(facade.gossipsub.is_none());
1155 }
1156
1157 #[tokio::test]
1158 async fn test_facade_with_semantic_dht() {
1159 let result = NetworkFacadeBuilder::new().with_semantic_dht().build();
1160 assert!(result.is_ok());
1161
1162 let facade = result.unwrap();
1163 assert!(facade.semantic_dht.is_some());
1164 }
1165
1166 #[tokio::test]
1167 async fn test_facade_with_all_features() {
1168 let result = NetworkFacadeBuilder::new()
1169 .with_semantic_dht()
1170 .with_gossipsub()
1171 .with_geo_routing()
1172 .with_quality_predictor()
1173 .with_bandwidth_throttle()
1174 .with_adaptive_polling()
1175 .with_memory_monitor()
1176 .with_network_monitor()
1177 .with_query_batcher()
1178 .build();
1179
1180 assert!(result.is_ok());
1181
1182 let facade = result.unwrap();
1183 assert!(facade.semantic_dht.is_some());
1184 assert!(facade.gossipsub.is_some());
1185 assert!(facade.geo_router.is_some());
1186 assert!(facade.quality_predictor.is_some());
1187 assert!(facade.bandwidth_throttle.is_some());
1188 assert!(facade.adaptive_polling.is_some());
1189 assert!(facade.memory_monitor.is_some());
1190 assert!(facade.network_monitor.is_some());
1191 assert!(facade.query_batcher.is_some());
1192 }
1193
1194 #[tokio::test]
1195 async fn test_facade_peer_id() {
1196 let facade = NetworkFacadeBuilder::new().build().unwrap();
1197 let peer_id = facade.peer_id();
1198 assert!(!peer_id.to_string().is_empty());
1199 }
1200
1201 #[tokio::test]
1202 async fn test_facade_connected_peers_empty() {
1203 let facade = NetworkFacadeBuilder::new().build().unwrap();
1204 let peers = facade.connected_peers();
1205 assert_eq!(peers.len(), 0);
1206 }
1207
1208 #[tokio::test]
1209 async fn test_facade_peer_count_zero() {
1210 let facade = NetworkFacadeBuilder::new().build().unwrap();
1211 assert_eq!(facade.peer_count(), 0);
1212 }
1213
1214 #[tokio::test]
1215 async fn test_facade_health() {
1216 let facade = NetworkFacadeBuilder::new().build().unwrap();
1217 let health = facade.get_health();
1218 assert!(matches!(health.status, _));
1219 }
1220
1221 #[tokio::test]
1222 async fn test_facade_bandwidth_stats() {
1223 let facade = NetworkFacadeBuilder::new().build().unwrap();
1224 assert_eq!(facade.bytes_sent(), 0);
1225 assert_eq!(facade.bytes_received(), 0);
1226 }
1227}