use crate::{
types::{SimpleMessage, SecureMessage, SecurityLevel, MessageType},
transport::MultiTransportRouter,
transport::abstraction::MessageUrgency,
transport::TransportRoute,
config::Config,
error::Result,
email_server::{SynapseEmailServer, ServerRecommendation},
router::SynapseRouter,
};
use crate::synapse::blockchain::serialization::{DateTimeWrapper, UuidWrapper};
use uuid::Uuid;
use chrono::Utc;
use std::{sync::Arc, collections::HashMap};
use tracing::{info, warn};
pub struct EnhancedSynapseRouter {
synapse_router: SynapseRouter,
multi_transport: Option<Arc<MultiTransportRouter>>,
email_server: Option<Arc<SynapseEmailServer>>,
#[allow(dead_code)]
config: Config,
our_global_id: String,
multi_transport_enabled: bool,
email_server_enabled: bool,
}
impl EnhancedSynapseRouter {
pub async fn new(config: Config, our_global_id: String) -> Result<Self> {
info!("Initializing enhanced Synapse router with multi-transport support and email server");
let synapse_router = crate::router::SynapseRouter::new(config.clone(), our_global_id.clone()).await?;
let multi_transport = match MultiTransportRouter::new(config.clone(), our_global_id.clone()).await {
Ok(mt_router) => {
info!("Multi-transport router initialized successfully");
Some(Arc::new(mt_router))
}
Err(e) => {
warn!("Failed to initialize multi-transport router: {}", e);
warn!("Falling back to email-only mode");
None
}
};
let email_server = match SynapseEmailServer::new().await {
Ok(server) => {
let connectivity = server.get_connectivity();
match &connectivity.recommended_config {
ServerRecommendation::RunLocalServer { smtp_port, imap_port, external_ip } => {
info!("Email server configured to run locally on {}:{}/{}", external_ip, smtp_port, imap_port);
Some(Arc::new(server))
}
ServerRecommendation::RelayOnly { reason } => {
info!("Email server configured for relay-only mode: {}", reason);
Some(Arc::new(server))
}
ServerRecommendation::ExternalProvider { reason } => {
warn!("Using external email provider: {}", reason);
warn!("Email server will not be started locally");
None
}
}
}
Err(e) => {
warn!("Failed to initialize email server: {}", e);
warn!("Will use external email provider only");
None
}
};
let multi_transport_enabled = multi_transport.is_some();
let email_server_enabled = email_server.is_some();
Ok(Self {
synapse_router,
multi_transport,
email_server,
config,
our_global_id,
multi_transport_enabled,
email_server_enabled,
})
}
pub async fn send_message_smart(
&self,
to_entity: &str,
content: &str,
message_type: MessageType,
security_level: SecurityLevel,
urgency: MessageUrgency,
) -> Result<String> {
info!("Sending smart message to {} (urgency: {:?})", to_entity, urgency);
if let Some(ref mt_router) = self.multi_transport {
if matches!(urgency, MessageUrgency::RealTime | MessageUrgency::Interactive) {
let simple_msg = SimpleMessage {
to: to_entity.to_string(),
from_entity: self.our_global_id.clone(),
content: content.to_string(),
message_type: message_type.clone(),
metadata: std::collections::HashMap::new(),
};
let secure_msg = self.create_secure_message(&simple_msg, security_level.clone()).await?;
match mt_router.send_message(to_entity, &secure_msg, urgency).await {
Ok(delivery_receipt) => {
let message_id = delivery_receipt.message_id.clone();
info!("Message sent via multi-transport: {}", message_id);
return Ok(message_id);
}
Err(e) => {
warn!("Multi-transport failed: {}, falling back to email", e);
}
}
}
}
info!("Using traditional email routing for {}", to_entity);
let simple_msg = SimpleMessage {
to: to_entity.to_string(),
from_entity: self.our_global_id.clone(),
content: content.to_string(),
message_type,
metadata: HashMap::new(),
};
self.synapse_router.send_message(simple_msg, to_entity.to_string()).await.map(|_| "email_fallback".to_string())
}
pub async fn send_message_with_transport(
&self,
to_entity: &str,
content: &str,
message_type: MessageType,
security_level: SecurityLevel,
preferred_routes: &[TransportRoute],
) -> Result<String> {
if let Some(ref mt_router) = self.multi_transport {
let simple_msg = SimpleMessage {
to: to_entity.to_string(),
from_entity: self.our_global_id.clone(),
content: content.to_string(),
message_type,
metadata: std::collections::HashMap::new(),
};
let secure_msg = self.create_secure_message(&simple_msg, security_level).await?;
return mt_router.send_with_fallback_priority(to_entity, &secure_msg, preferred_routes).await
.map(|receipt| receipt.message_id);
}
let simple_msg = SimpleMessage {
to: to_entity.to_string(),
from_entity: self.our_global_id.clone(),
content: content.to_string(),
message_type,
metadata: HashMap::new(),
};
self.synapse_router.send_message(simple_msg, to_entity.to_string()).await.map(|_| "email_fallback".to_string())
}
pub async fn test_connection(&self, target: &str) -> ConnectionCapabilities {
let mut capabilities = ConnectionCapabilities {
email: true, direct_tcp: false,
direct_udp: false,
mdns_local: false,
nat_traversal: false,
estimated_latency_ms: 60_000, };
if let Some(ref mt_router) = self.multi_transport {
capabilities.direct_tcp = mt_router.can_connect_directly(target).await;
if mt_router.discover_local_peer(target).await.is_ok() {
capabilities.mdns_local = true;
capabilities.estimated_latency_ms = 50; }
if mt_router.establish_nat_traversal(target).await.is_ok() {
capabilities.nat_traversal = true;
capabilities.estimated_latency_ms = capabilities.estimated_latency_ms.min(200);
}
if capabilities.direct_tcp || capabilities.direct_udp {
capabilities.estimated_latency_ms = capabilities.estimated_latency_ms.min(100);
}
}
capabilities
}
pub async fn start(&self) -> Result<()> {
info!("Starting enhanced Synapse router");
if let Some(ref email_server) = self.email_server {
email_server.start().await?;
info!("Email server started successfully");
}
if let Some(ref mt_router) = self.multi_transport {
mt_router.start_background_services().await?;
info!("Multi-transport services started");
}
info!("Enhanced EMRP router fully started");
Ok(())
}
pub async fn status(&self) -> EnhancedRouterStatus {
let synapse_status = self.synapse_router.get_health().await;
let mut capabilities = vec!["email".to_string()];
if let Some(ref mt_router) = self.multi_transport {
capabilities.extend(mt_router.get_capabilities());
}
if self.email_server_enabled {
capabilities.push("smtp-server".to_string());
capabilities.push("imap-server".to_string());
}
EnhancedRouterStatus {
synapse_status,
multi_transport_enabled: self.multi_transport_enabled,
email_server_enabled: self.email_server_enabled,
available_transports: capabilities,
}
}
async fn create_secure_message(
&self,
simple_msg: &SimpleMessage,
security_level: SecurityLevel,
) -> Result<SecureMessage> {
let message_id = UuidWrapper::new(Uuid::new_v4());
let timestamp = DateTimeWrapper::new(Utc::now());
Ok(SecureMessage {
message_id,
to_global_id: simple_msg.to.clone(),
from_global_id: self.our_global_id.clone(),
timestamp,
security_level,
encrypted_content: simple_msg.content.as_bytes().to_vec(),
signature: Vec::new(),
routing_path: Vec::new(),
metadata: simple_msg.metadata.clone(),
})
}
pub async fn benchmark_transport(&self, target: &str) -> TransportBenchmarks {
let mut benchmarks = TransportBenchmarks {
email_latency_ms: 60_000,
tcp_latency_ms: None,
udp_latency_ms: None,
mdns_latency_ms: None,
nat_traversal_latency_ms: None,
};
if let Some(ref mt_router) = self.multi_transport {
let test_message = SecureMessage {
message_id: UuidWrapper::new(Uuid::new_v4()),
to_global_id: target.to_string(),
from_global_id: self.our_global_id.clone(),
timestamp: DateTimeWrapper::new(Utc::now()),
security_level: SecurityLevel::Public,
encrypted_content: b"benchmark test".to_vec(),
signature: Vec::new(),
routing_path: Vec::new(),
metadata: std::collections::HashMap::new(),
};
let test_routes = vec![
TransportRoute::DirectTcp {
address: target.to_string(),
port: 8080,
latency_ms: 0,
established_at: std::time::Instant::now(),
},
TransportRoute::DirectUdp {
address: target.to_string(),
port: 8080,
latency_ms: 0,
established_at: std::time::Instant::now(),
},
TransportRoute::LocalMdns {
service_name: target.to_string(),
address: target.to_string(),
port: 5353,
latency_ms: 0,
discovered_at: std::time::Instant::now(),
},
];
for route in test_routes {
let start = std::time::Instant::now();
match mt_router.send_with_fallback_priority(target, &test_message, &[route.clone()]).await {
Ok(_) => {
let latency = start.elapsed().as_millis() as u32;
match route {
TransportRoute::DirectTcp { .. } => benchmarks.tcp_latency_ms = Some(latency),
TransportRoute::DirectUdp { .. } => benchmarks.udp_latency_ms = Some(latency),
TransportRoute::LocalMdns { .. } => benchmarks.mdns_latency_ms = Some(latency),
_ => {}
}
}
Err(_) => {
}
}
}
}
benchmarks
}
pub fn email_server(&self) -> Option<Arc<SynapseEmailServer>> {
self.email_server.clone()
}
pub fn is_running_email_server(&self) -> bool {
self.email_server_enabled && self.email_server.is_some()
}
pub fn email_server_connectivity(&self) -> Option<String> {
if let Some(ref server) = self.email_server {
let connectivity = server.get_connectivity();
Some(format!("{:?}", connectivity.recommended_config))
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub struct ConnectionCapabilities {
pub email: bool,
pub direct_tcp: bool,
pub direct_udp: bool,
pub mdns_local: bool,
pub nat_traversal: bool,
pub estimated_latency_ms: u32,
}
#[derive(Debug, Clone)]
pub struct EnhancedRouterStatus {
pub synapse_status: super::router::RouterHealth,
pub multi_transport_enabled: bool,
pub email_server_enabled: bool,
pub available_transports: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct TransportBenchmarks {
pub email_latency_ms: u32,
pub tcp_latency_ms: Option<u32>,
pub udp_latency_ms: Option<u32>,
pub mdns_latency_ms: Option<u32>,
pub nat_traversal_latency_ms: Option<u32>,
}