#![allow(non_snake_case)]
use std::collections::HashMap as FxHashMap;
use std::sync::Arc;
use std::time::Instant;
use tokio::sync::{RwLock, mpsc};
use uuid::Uuid;
use crate::core::{RiResult};
pub struct RiIntegrationEventBus {
pub subscribers: Arc<RwLock<FxHashMap<RiIntegrationEventType, Vec<mpsc::Sender<RiIntegrationEvent>>>>>,
pub stats: Arc<RwLock<RiIntegrationEventStats>>,
}
const MAX_EVENT_DATA_ENTRIES: usize = 100;
const MAX_EVENT_DATA_KEY_LENGTH: usize = 256;
const MAX_EVENT_DATA_VALUE_LENGTH: usize = 4096;
const MAX_EVENT_SOURCE_LENGTH: usize = 256;
#[derive(Debug, Clone)]
pub struct RiIntegrationEvent {
pub event_id: String,
pub event_type: RiIntegrationEventType,
pub event_data: FxHashMap<String, String>,
pub event_timestamp: Instant,
pub event_source: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RiIntegrationEventType {
ProtocolRegistered,
ProtocolUnregistered,
ProtocolSwitched,
ConnectionEstablished,
ConnectionTerminated,
StateSynchronized,
SecurityEvent,
PerformanceEvent,
ErrorEvent,
PerformanceMetrics,
}
#[derive(Debug, Default)]
pub struct RiIntegrationEventStats {
pub total_events: u64,
pub events_by_type: FxHashMap<RiIntegrationEventType, u64>,
pub avg_event_processing_time_ms: u64,
}
#[derive(Debug, Default)]
pub struct RiIntegrationStats {
pub total_cross_protocol_messages: u64,
pub successful_cross_protocol_messages: u64,
pub failed_cross_protocol_messages: u64,
pub protocol_switches: u64,
pub successful_protocol_switches: u64,
pub failed_protocol_switches: u64,
pub state_synchronizations: u64,
pub avg_cross_protocol_latency_ms: u64,
pub avg_protocol_switching_time_ms: u64,
}
impl RiIntegrationEventBus {
pub async fn publish_event(&self, event_type: RiIntegrationEventType, event_data: FxHashMap<String, String>) -> RiResult<()> {
if event_data.len() > MAX_EVENT_DATA_ENTRIES {
return Err(crate::core::RiError::Other(format!(
"Event data exceeds maximum entries: {} (max {})",
event_data.len(), MAX_EVENT_DATA_ENTRIES
)));
}
let mut safe_data = FxHashMap::with_capacity(event_data.len());
for (key, value) in event_data {
if key.len() > MAX_EVENT_DATA_KEY_LENGTH {
return Err(crate::core::RiError::Other(format!(
"Event data key too long: {} chars (max {})",
key.len(), MAX_EVENT_DATA_KEY_LENGTH
)));
}
let safe_value = if value.len() > MAX_EVENT_DATA_VALUE_LENGTH {
&value[..MAX_EVENT_DATA_VALUE_LENGTH]
} else {
&value
};
if key.chars().any(|c| c.is_control()) {
return Err(crate::core::RiError::Other(
"Event data key contains control characters".to_string()
));
}
safe_data.insert(key, safe_value.to_string());
}
let event = RiIntegrationEvent {
event_id: Uuid::new_v4().to_string(),
event_type,
event_data: safe_data,
event_timestamp: Instant::now(),
event_source: "global-system-integration".to_string(),
};
self.stats.write().await.total_events += 1;
let subscribers = self.subscribers.read().await;
if let Some(subscribers) = subscribers.get(&event_type) {
for subscriber in subscribers {
let _ = subscriber.send(event.clone()).await;
}
}
Ok(())
}
}