use super::threading::{self, ThreadingEngine};
use rusmes_proto::MessageId;
use std::path::Path;
use std::str::FromStr;
pub(super) async fn scan_for_thread_id(
mailboxes_dir: &Path,
message_id: &MessageId,
) -> anyhow::Result<Option<String>> {
if !tokio::fs::try_exists(mailboxes_dir).await.unwrap_or(false) {
return Ok(None);
}
let mut mailbox_entries = tokio::fs::read_dir(mailboxes_dir).await?;
while let Some(mbx_entry) = mailbox_entries.next_entry().await? {
let mbx_file_type = match mbx_entry.file_type().await {
Ok(ft) => ft,
Err(_) => continue,
};
if !mbx_file_type.is_dir() {
continue;
}
let mailbox_dir = mbx_entry.path();
for subdir in ["new", "cur"] {
let msg_dir = mailbox_dir.join(subdir);
if !tokio::fs::try_exists(&msg_dir).await.unwrap_or(false) {
continue;
}
let mut msg_entries = match tokio::fs::read_dir(&msg_dir).await {
Ok(e) => e,
Err(_) => continue,
};
while let Some(msg_entry) = msg_entries.next_entry().await? {
let msg_ft = match msg_entry.file_type().await {
Ok(ft) => ft,
Err(_) => continue,
};
if !msg_ft.is_file() {
continue;
}
let file_path = msg_entry.path();
let data = match tokio::fs::read(&file_path).await {
Ok(d) => d,
Err(_) => continue,
};
let mime = match rusmes_proto::MimeMessage::parse_from_bytes(&data) {
Ok(m) => m,
Err(_) => continue,
};
let stored_id =
mime.headers()
.get_first("x-rusmes-message-id")
.and_then(|id_str| {
uuid::Uuid::from_str(id_str.trim())
.ok()
.map(MessageId::from_uuid)
});
if stored_id.as_ref() == Some(message_id) {
if let Some(rfc_id) = mime
.headers()
.get_first("message-id")
.map(threading::strip_angle_brackets)
{
let engine = ThreadingEngine::new(&mailbox_dir);
return engine.get_thread_id(&rfc_id).await;
}
return Ok(None);
}
}
}
}
Ok(None)
}