use log::debug;
use std::sync::Arc;
use tap_agent::Agent;
use tap_msg::didcomm::PlainMessage;
use crate::agent::AgentRegistry;
use crate::error::{Error, Result};
use crate::message::PlainMessageRouter;
#[derive(Debug, Clone)]
pub struct DefaultPlainMessageRouter {
agents: Option<Arc<AgentRegistry>>,
}
impl Default for DefaultPlainMessageRouter {
fn default() -> Self {
Self::new()
}
}
impl DefaultPlainMessageRouter {
pub fn new() -> Self {
Self { agents: None }
}
pub fn with_agents(mut self, agents: Arc<AgentRegistry>) -> Self {
self.agents = Some(agents);
self
}
}
impl PlainMessageRouter for DefaultPlainMessageRouter {
fn route_message_impl(&self, message: &PlainMessage) -> Result<String> {
if !message.to.is_empty() {
{
let to_did = message.to[0].clone();
if let Some(agents) = &self.agents {
if agents.has_agent(&to_did) {
debug!("Routing message to: {}", to_did);
return Ok(to_did);
}
} else {
debug!("No agent registry available, routing to: {}", to_did);
return Ok(to_did);
}
}
}
Err(Error::Dispatch(format!(
"No route found for message: {}",
message.id
)))
}
}
#[derive(Debug, Default)]
pub struct CompositePlainMessageRouter {
routers: Vec<crate::message::PlainMessageRouterType>,
}
impl CompositePlainMessageRouter {
pub fn new() -> Self {
Self::default()
}
pub fn add_router(&mut self, router: crate::message::PlainMessageRouterType) {
self.routers.push(router);
}
}
impl PlainMessageRouter for CompositePlainMessageRouter {
fn route_message_impl(&self, message: &PlainMessage) -> Result<String> {
for router in &self.routers {
match router {
crate::message::PlainMessageRouterType::Default(r) => {
match r.route_message_impl(message) {
Ok(target) => return Ok(target),
Err(_) => continue, }
}
crate::message::PlainMessageRouterType::IntraNode(r) => {
match r.route_message_impl(message) {
Ok(target) => return Ok(target),
Err(_) => continue, }
}
}
}
Err(Error::Dispatch(format!(
"No route found for message: {}",
message.id
)))
}
}
#[derive(Debug, Clone)]
pub struct IntraNodePlainMessageRouter {
agents: Option<Arc<AgentRegistry>>,
}
impl Default for IntraNodePlainMessageRouter {
fn default() -> Self {
Self::new()
}
}
impl IntraNodePlainMessageRouter {
pub fn new() -> Self {
Self { agents: None }
}
pub fn with_agents(mut self, agents: Arc<AgentRegistry>) -> Self {
self.agents = Some(agents);
self
}
async fn route_to_local_agents(&self, message: &PlainMessage) -> Result<Vec<String>> {
let mut local_recipients = Vec::new();
if let Some(agents) = &self.agents {
for recipient in &message.to {
if agents.has_agent(recipient) {
local_recipients.push(recipient.clone());
}
}
}
Ok(local_recipients)
}
pub async fn deliver_to_local_agents(&self, message: &PlainMessage) -> Result<()> {
if let Some(agents) = &self.agents {
let local_recipients = self.route_to_local_agents(message).await?;
for recipient_did in local_recipients {
if let Ok(agent) = agents.get_agent(&recipient_did).await {
if let Err(e) = agent.receive_plain_message(message.clone()).await {
log::warn!(
"Failed to deliver message {} to local agent {}: {}",
message.id,
recipient_did,
e
);
} else {
log::debug!(
"Delivered message {} to local agent {}",
message.id,
recipient_did
);
}
}
}
}
Ok(())
}
}
impl PlainMessageRouter for IntraNodePlainMessageRouter {
fn route_message_impl(&self, message: &PlainMessage) -> Result<String> {
if let Some(agents) = &self.agents {
for recipient in &message.to {
if agents.has_agent(recipient) {
debug!("Routing message to local agent: {}", recipient);
return Ok(recipient.clone());
}
}
}
Err(Error::Dispatch(format!(
"No local agents found for message: {}",
message.id
)))
}
}