ipfrs_network/
facade.rs

1//! High-level network facade integrating all IPFRS network modules
2//!
3//! This module provides a unified interface to all network functionality,
4//! making it easy to use advanced features without manual wiring.
5//!
6//! # Example
7//!
8//! ```rust,no_run
9//! use ipfrs_network::NetworkFacadeBuilder;
10//!
11//! #[tokio::main]
12//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
13//!     let mut facade = NetworkFacadeBuilder::new()
14//!         .with_preset_mobile()
15//!         .with_semantic_dht()
16//!         .with_gossipsub()
17//!         .with_geo_routing()
18//!         .build()?;
19//!
20//!     facade.start().await?;
21//!
22//!     // Use integrated features
23//!     let health = facade.get_health();
24//!     println!("Network health: {:?}", health.status);
25//!
26//!     Ok(())
27//! }
28//! ```
29
30use 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/// Comprehensive network statistics
59#[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/// Detailed module status
74#[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
92/// High-level network facade integrating all modules
93pub struct NetworkFacade {
94    /// Core network node
95    pub node: NetworkNode,
96
97    /// Optional modules
98    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    /// Always-available supporting modules
114    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    /// Create a new network facade with default configuration
121    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    /// Start the network node and all enabled modules
152    pub async fn start(&mut self) -> IpfrsResult<()> {
153        self.node.start().await?;
154
155        // Start Tor if enabled
156        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    /// Stop the network node and all modules
166    pub async fn stop(&mut self) -> IpfrsResult<()> {
167        // Stop Tor if enabled
168        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    /// Get peer ID
178    pub fn peer_id(&self) -> PeerId {
179        self.node.peer_id()
180    }
181
182    /// Get connected peers
183    pub fn connected_peers(&self) -> Vec<PeerId> {
184        self.node.connected_peers()
185    }
186
187    /// Connect to a peer
188    pub async fn connect(&mut self, addr: Multiaddr) -> IpfrsResult<()> {
189        self.node.connect(addr).await
190    }
191
192    /// Disconnect from a peer
193    pub async fn disconnect(&mut self, peer_id: PeerId) -> IpfrsResult<()> {
194        self.node.disconnect(peer_id).await
195    }
196
197    /// Provide content to the DHT
198    pub async fn provide(&mut self, cid: &cid::Cid) -> IpfrsResult<()> {
199        self.node.provide(cid).await
200    }
201
202    /// Find providers for content
203    pub async fn find_providers(&mut self, cid: &cid::Cid) -> IpfrsResult<()> {
204        self.node.find_providers(cid).await
205    }
206
207    /// Get network health summary
208    pub fn get_health(&self) -> NetworkHealthSummary {
209        self.node.get_network_health()
210    }
211
212    /// Check if network is healthy
213    pub fn is_healthy(&self) -> bool {
214        self.node.is_healthy()
215    }
216
217    /// Get peer count
218    pub fn peer_count(&self) -> usize {
219        self.node.get_peer_count()
220    }
221
222    /// Check if connected to peer
223    pub fn is_connected_to(&self, peer_id: &PeerId) -> bool {
224        self.node.is_connected_to(peer_id)
225    }
226
227    /// Get bytes sent
228    pub fn bytes_sent(&self) -> u64 {
229        self.node.get_bytes_sent()
230    }
231
232    /// Get bytes received
233    pub fn bytes_received(&self) -> u64 {
234        self.node.get_bytes_received()
235    }
236
237    /// Add a Tor manager after creation (requires async initialization)
238    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    // ============================================================================
248    // Semantic DHT Operations (when enabled)
249    // ============================================================================
250
251    /// Perform semantic search using vector embeddings (requires semantic_dht)
252    ///
253    /// # Returns
254    /// Returns an error if semantic DHT is not enabled
255    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    /// Index content with semantic embedding (requires semantic_dht)
279    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    /// Register a semantic namespace (requires semantic_dht)
297    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    // ============================================================================
319    // GossipSub Operations (when enabled)
320    // ============================================================================
321
322    /// Subscribe to a topic (requires gossipsub)
323    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    /// Unsubscribe from a topic (requires gossipsub)
336    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    /// Publish a message to a topic (requires gossipsub)
349    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    /// Get subscribed topics (requires gossipsub)
363    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        // Note: subscriptions field is private, so we return an empty list for now
369        // This would need to be exposed by the GossipSubManager API
370        Ok(Vec::new())
371    }
372
373    // ============================================================================
374    // Geographic & Quality-Based Operations (when enabled)
375    // ============================================================================
376
377    /// Find nearby peers based on geographic location (requires geo_routing)
378    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    /// Set location for a peer (requires geo_routing)
395    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    /// Get best quality peers for content transfer (requires quality_predictor)
409    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    /// Select optimal peers (requires peer_selector)
424    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    // ============================================================================
441    // Network Diagnostics & Statistics
442    // ============================================================================
443
444    /// Get comprehensive network statistics
445    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    /// Get detailed module status
461    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    /// Get memory usage statistics (requires memory_monitor)
481    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    // ============================================================================
490    // Batch Operations
491    // ============================================================================
492
493    /// Connect to multiple peers concurrently
494    pub async fn connect_batch(&mut self, addrs: Vec<Multiaddr>) -> Vec<IpfrsResult<()>> {
495        self.node.connect_to_peers(addrs).await
496    }
497
498    /// Announce multiple CIDs to the DHT
499    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    /// Find providers for multiple CIDs
508    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    // ============================================================================
517    // Configuration & Inspection
518    // ============================================================================
519
520    /// Check if a specific module is enabled
521    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    /// Get list of enabled module names
542    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    /// Get human-readable summary of the network facade configuration
573    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
586/// Builder for NetworkFacade
587pub 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    /// Create a new builder with default configuration
624    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    /// Use a preset configuration
661    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    /// Use mobile preset
726    pub fn with_preset_mobile(self) -> Self {
727        self.with_preset(NetworkPreset::mobile())
728    }
729
730    /// Use IoT preset
731    pub fn with_preset_iot(self) -> Self {
732        self.with_preset(NetworkPreset::iot())
733    }
734
735    /// Use low-memory preset
736    pub fn with_preset_low_memory(self) -> Self {
737        self.with_preset(NetworkPreset::low_memory())
738    }
739
740    /// Use high-performance preset
741    pub fn with_preset_high_performance(self) -> Self {
742        self.with_preset(NetworkPreset::high_performance())
743    }
744
745    /// Use privacy preset
746    pub fn with_preset_privacy(self) -> Self {
747        self.with_preset(NetworkPreset::privacy())
748    }
749
750    /// Set custom network configuration
751    pub fn with_config(mut self, config: NetworkConfig) -> Self {
752        self.config = config;
753        self
754    }
755
756    /// Enable semantic DHT
757    pub fn with_semantic_dht(mut self) -> Self {
758        self.enable_semantic_dht = true;
759        self
760    }
761
762    /// Enable semantic DHT with custom config
763    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    /// Enable GossipSub
770    pub fn with_gossipsub(mut self) -> Self {
771        self.enable_gossipsub = true;
772        self
773    }
774
775    /// Enable GossipSub with custom config
776    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    /// Enable geographic routing
783    pub fn with_geo_routing(mut self) -> Self {
784        self.enable_geo_routing = true;
785        self
786    }
787
788    /// Enable geographic routing with custom config
789    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    /// Enable quality prediction
796    pub fn with_quality_predictor(mut self) -> Self {
797        self.enable_quality_predictor = true;
798        self
799    }
800
801    /// Enable quality prediction with custom config
802    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    /// Enable intelligent peer selection
809    pub fn with_peer_selector(mut self) -> Self {
810        self.enable_peer_selector = true;
811        self
812    }
813
814    /// Enable intelligent peer selection with custom config
815    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    /// Enable multipath QUIC
822    pub fn with_multipath_quic(mut self) -> Self {
823        self.enable_multipath_quic = true;
824        self
825    }
826
827    /// Enable multipath QUIC with custom config
828    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    /// Enable Tor integration
835    pub fn with_tor(mut self) -> Self {
836        self.enable_tor = true;
837        self
838    }
839
840    /// Enable Tor with custom config
841    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    /// Enable bandwidth throttling
848    pub fn with_bandwidth_throttle(mut self) -> Self {
849        self.enable_bandwidth_throttle = true;
850        self
851    }
852
853    /// Enable bandwidth throttling with custom config
854    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    /// Enable adaptive polling
861    pub fn with_adaptive_polling(mut self) -> Self {
862        self.enable_adaptive_polling = true;
863        self
864    }
865
866    /// Enable adaptive polling with custom config
867    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    /// Enable background mode
874    pub fn with_background_mode(mut self) -> Self {
875        self.enable_background_mode = true;
876        self
877    }
878
879    /// Enable background mode with custom config
880    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    /// Enable offline queue
887    pub fn with_offline_queue(mut self) -> Self {
888        self.enable_offline_queue = true;
889        self
890    }
891
892    /// Enable offline queue with custom config
893    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    /// Enable memory monitoring
900    pub fn with_memory_monitor(mut self) -> Self {
901        self.enable_memory_monitor = true;
902        self
903    }
904
905    /// Enable memory monitoring with custom config
906    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    /// Enable network monitoring
913    pub fn with_network_monitor(mut self) -> Self {
914        self.enable_network_monitor = true;
915        self
916    }
917
918    /// Enable network monitoring with custom config
919    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    /// Enable query batching
926    pub fn with_query_batcher(mut self) -> Self {
927        self.enable_query_batcher = true;
928        self
929    }
930
931    /// Enable query batching with custom config
932    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    /// Build the network facade
939    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            // Note: TorManager requires async initialization, so it's not created in the builder
1011            // Users should use with_tor_manager() after building the facade if Tor is needed
1012            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}