use anyhow::Result;
use uuid::Uuid;
use crate::services::SessionService;
pub fn chat_id_suffix(id: &str) -> String {
format!("[chat:{id}]")
}
pub fn session_idle_expired(
updated_at: chrono::DateTime<chrono::Utc>,
idle_hours: Option<f64>,
) -> bool {
idle_hours.is_some_and(|h| {
let elapsed = (chrono::Utc::now() - updated_at).num_seconds();
elapsed > (h * 3600.0) as i64
})
}
pub async fn resolve_or_create_channel_session(
session_svc: &SessionService,
suffix: &str,
legacy_title: &str,
current_title: &str,
idle_hours: Option<f64>,
log_prefix: &str,
) -> Result<Uuid> {
let mut existing = session_svc
.find_session_by_title_suffix(suffix)
.await
.ok()
.flatten();
if existing.is_none()
&& let Ok(Some(legacy)) = session_svc.find_session_by_title(legacy_title).await
{
tracing::info!(
"{}: forward-migrating legacy session {} '{}' → '{}'",
log_prefix,
legacy.id,
legacy.title.as_deref().unwrap_or(""),
current_title,
);
let mut migrated = legacy.clone();
migrated.title = Some(current_title.to_string());
if let Err(e) = session_svc.update_session(&migrated).await {
tracing::warn!(
"{}: failed to forward-migrate session {} title: {}",
log_prefix,
legacy.id,
e
);
existing = Some(legacy);
} else {
existing = Some(migrated);
}
}
if let Some(session) = existing {
if session_idle_expired(session.updated_at, idle_hours) {
if let Err(e) = session_svc.archive_session(session.id).await {
tracing::error!(
"{}: failed to archive idle session {}: {}",
log_prefix,
session.id,
e,
);
}
let new_session = crate::channels::session_init::create_channel_session(
session_svc,
Some(current_title.to_string()),
)
.await?;
tracing::info!(
"{}: idle-timeout reset — new session {} for \"{}\"",
log_prefix,
new_session.id,
current_title,
);
Ok(new_session.id)
} else {
Ok(session.id)
}
} else {
let new_session = crate::channels::session_init::create_channel_session(
session_svc,
Some(current_title.to_string()),
)
.await?;
tracing::info!(
"{}: created new channel session {} for \"{}\"",
log_prefix,
new_session.id,
current_title,
);
Ok(new_session.id)
}
}