use std::collections::HashSet;
use chrono::{DateTime, Utc};
use super::super::types::OmObserverMessageCandidate;
pub fn select_observer_message_candidates(
candidates: &[OmObserverMessageCandidate],
observed_message_ids: &HashSet<String>,
max_messages: usize,
) -> Vec<OmObserverMessageCandidate> {
if max_messages == 0 {
return Vec::new();
}
let mut filtered = candidates
.iter()
.filter(|candidate| {
!candidate.id.trim().is_empty() && !observed_message_ids.contains(&candidate.id)
})
.cloned()
.collect::<Vec<_>>();
filtered.sort_by(|a, b| {
a.created_at
.cmp(&b.created_at)
.then_with(|| a.source_session_id.cmp(&b.source_session_id))
.then_with(|| a.id.cmp(&b.id))
});
if filtered.len() > max_messages {
filtered = filtered[filtered.len() - max_messages..].to_vec();
}
filtered
}
pub fn filter_observer_candidates_by_last_observed_at(
candidates: &[OmObserverMessageCandidate],
last_observed_at: Option<DateTime<Utc>>,
) -> Vec<OmObserverMessageCandidate> {
let Some(cutoff) = last_observed_at else {
return candidates.to_vec();
};
candidates
.iter()
.filter(|candidate| candidate.created_at > cutoff)
.cloned()
.collect::<Vec<_>>()
}
pub fn split_pending_and_other_conversation_candidates(
candidates: &[OmObserverMessageCandidate],
current_session_id: Option<&str>,
) -> (
Vec<OmObserverMessageCandidate>,
Vec<OmObserverMessageCandidate>,
) {
let mut pending = Vec::<OmObserverMessageCandidate>::new();
let mut other_conversations = Vec::<OmObserverMessageCandidate>::new();
let normalized_current_session_id = current_session_id
.map(str::trim)
.filter(|value| !value.is_empty());
for candidate in candidates {
let source_session_id = candidate
.source_session_id
.as_deref()
.map(str::trim)
.filter(|value| !value.is_empty());
let is_pending = match (normalized_current_session_id, source_session_id) {
(Some(current), Some(source)) => source == current,
(Some(_), None) => true,
(None, _) => true,
};
if is_pending {
pending.push(candidate.clone());
} else {
other_conversations.push(candidate.clone());
}
}
(pending, other_conversations)
}
pub fn select_observed_message_candidates(
candidates: &[OmObserverMessageCandidate],
observed_message_ids: &[String],
) -> Vec<OmObserverMessageCandidate> {
if observed_message_ids.is_empty() {
return candidates.to_vec();
}
let observed = observed_message_ids
.iter()
.map(String::as_str)
.collect::<HashSet<_>>();
candidates
.iter()
.filter(|item| observed.contains(item.id.as_str()))
.cloned()
.collect::<Vec<_>>()
}