use crate::aggregators::StateAggregator;
use crate::model::{NodeType, StateEdge, StateLayer, StateNode};
use async_trait::async_trait;
use mockforge_core::consistency::types::UnifiedState;
use std::sync::{Arc, RwLock as StdRwLock};
pub struct ProtocolAggregator {
unified_state: Option<Arc<StdRwLock<UnifiedState>>>,
}
impl ProtocolAggregator {
pub fn new(unified_state: Option<Arc<StdRwLock<UnifiedState>>>) -> Self {
Self { unified_state }
}
}
#[async_trait]
impl StateAggregator for ProtocolAggregator {
async fn aggregate(&self) -> anyhow::Result<(Vec<StateNode>, Vec<StateEdge>)> {
let mut nodes = Vec::new();
let mut edges = Vec::new();
if let Some(ref state) = self.unified_state {
let state = state.read().unwrap();
let mut workspace_node = StateNode::new(
format!("workspace:{}", state.workspace_id),
format!("Workspace: {}", state.workspace_id),
NodeType::System,
StateLayer::Protocols,
);
workspace_node
.set_property("workspace_id".to_string(), serde_json::json!(state.workspace_id));
workspace_node.set_property(
"reality_level".to_string(),
serde_json::json!(format!("{:?}", state.reality_level)),
);
workspace_node.set_property(
"reality_continuum_ratio".to_string(),
serde_json::json!(state.reality_continuum_ratio),
);
nodes.push(workspace_node);
for (protocol, protocol_state) in &state.protocol_states {
let mut protocol_node = StateNode::new(
format!("protocol:{:?}", protocol),
format!("Protocol: {:?}", protocol),
NodeType::Protocol,
StateLayer::Protocols,
);
protocol_node.set_property(
"protocol".to_string(),
serde_json::json!(format!("{:?}", protocol)),
);
protocol_node.set_property(
"active_sessions".to_string(),
serde_json::json!(protocol_state.active_sessions.len()),
);
nodes.push(protocol_node);
let edge = StateEdge::new(
format!("workspace:{}", state.workspace_id),
format!("protocol:{:?}", protocol),
"has_protocol".to_string(),
);
edges.push(edge);
for session in &protocol_state.active_sessions {
let mut session_node = StateNode::new(
format!("session:{}", session.session_id),
format!("Session: {}", session.session_id),
NodeType::Session,
StateLayer::Protocols,
);
session_node.set_property(
"session_id".to_string(),
serde_json::json!(session.session_id),
);
if let Some(ref persona_id) = session.persona_id {
session_node
.set_property("persona_id".to_string(), serde_json::json!(persona_id));
}
nodes.push(session_node);
let edge = StateEdge::new(
format!("protocol:{:?}", protocol),
format!("session:{}", session.session_id),
"has_session".to_string(),
);
edges.push(edge);
}
}
for (entity_key, entity_state) in &state.entity_state {
let mut entity_node = StateNode::new(
format!("entity:{}", entity_key),
format!("Entity: {}", entity_key),
NodeType::Entity,
StateLayer::Protocols,
);
entity_node.set_property(
"entity_type".to_string(),
serde_json::json!(entity_state.entity_type),
);
entity_node.set_property(
"entity_id".to_string(),
serde_json::json!(entity_state.entity_id),
);
nodes.push(entity_node);
let edge = StateEdge::new(
format!("workspace:{}", state.workspace_id),
format!("entity:{}", entity_key),
"has_entity".to_string(),
);
edges.push(edge);
}
}
Ok((nodes, edges))
}
fn layer(&self) -> StateLayer {
StateLayer::Protocols
}
}