use crate::db::MissionDB;
use crate::types::InboxMessage;
use std::sync::Arc;
use tracing::{debug, info};
use uuid::Uuid;
pub struct Inbox {
db: Arc<MissionDB>,
}
impl Inbox {
pub fn new(db: Arc<MissionDB>) -> Self {
Self { db }
}
pub fn get_messages(&self, unread_only: bool, limit: usize) -> Vec<InboxMessage> {
self.db
.get_inbox_messages(unread_only, limit as i64)
.unwrap_or_default()
}
pub fn mark_read(&self, message_id: &str) {
let _ = self.db.mark_inbox_read(message_id);
debug!(message_id = %message_id, "Message marked as read");
}
pub fn mark_all_read(&self) {
let messages = self
.db
.get_inbox_messages(true, 10000)
.unwrap_or_default();
let count = messages.len();
for msg in messages {
let _ = self.db.mark_inbox_read(&msg.id);
}
info!(count = count, "All messages marked as read");
}
pub fn get_unread_count(&self) -> usize {
self.db
.get_inbox_messages(true, 10000)
.map(|v| v.len())
.unwrap_or(0)
}
pub fn add_message(&self, task_id: &str, from_role: &str, content: &str) {
let msg = InboxMessage {
id: Uuid::new_v4().to_string(),
task_id: task_id.to_string(),
from_role: from_role.to_string(),
content: content.to_string(),
read: false,
created_at: chrono::Utc::now().timestamp_millis(),
};
let _ = self.db.insert_inbox_message(&msg);
debug!(message_id = %msg.id, task_id = %task_id, "Message added to inbox");
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
fn create_test_db() -> Arc<MissionDB> {
let dir = tempdir().unwrap();
let db_path = dir.path().join("test.db");
Arc::new(MissionDB::open(db_path).unwrap())
}
#[test]
fn test_add_and_get_messages() {
let db = create_test_db();
let inbox = Inbox::new(db);
inbox.add_message("task-1", "worker", "Result 1");
inbox.add_message("task-2", "specialist", "Result 2");
let messages = inbox.get_messages(false, 10);
assert_eq!(messages.len(), 2);
let unread = inbox.get_messages(true, 10);
assert_eq!(unread.len(), 2);
assert!(messages.iter().any(|m| m.content == "Result 1"));
assert!(messages.iter().any(|m| m.content == "Result 2"));
}
#[test]
fn test_mark_read() {
let db = create_test_db();
let inbox = Inbox::new(db);
inbox.add_message("task-1", "worker", "Result");
let messages = inbox.get_messages(true, 10);
assert_eq!(messages.len(), 1);
let msg_id = &messages[0].id;
inbox.mark_read(msg_id);
let unread = inbox.get_messages(true, 10);
assert_eq!(unread.len(), 0);
let all = inbox.get_messages(false, 10);
assert_eq!(all.len(), 1);
}
#[test]
fn test_mark_all_read() {
let db = create_test_db();
let inbox = Inbox::new(db);
inbox.add_message("task-1", "worker", "Result 1");
inbox.add_message("task-2", "worker", "Result 2");
inbox.add_message("task-3", "worker", "Result 3");
assert_eq!(inbox.get_unread_count(), 3);
inbox.mark_all_read();
assert_eq!(inbox.get_unread_count(), 0);
}
#[test]
fn test_get_unread_count() {
let db = create_test_db();
let inbox = Inbox::new(db);
assert_eq!(inbox.get_unread_count(), 0);
inbox.add_message("task-1", "worker", "Result 1");
assert_eq!(inbox.get_unread_count(), 1);
inbox.add_message("task-2", "worker", "Result 2");
assert_eq!(inbox.get_unread_count(), 2);
let messages = inbox.get_messages(true, 1);
inbox.mark_read(&messages[0].id);
assert_eq!(inbox.get_unread_count(), 1);
}
#[test]
fn test_limit() {
let db = create_test_db();
let inbox = Inbox::new(db);
for i in 0..5 {
inbox.add_message(&format!("task-{}", i), "worker", &format!("Result {}", i));
}
let messages = inbox.get_messages(true, 3);
assert_eq!(messages.len(), 3);
}
}