use super::session::{Session, SessionStrategy};
use anyhow::Result;
use rusqlite::{params, OptionalExtension};
pub struct InspectSwap {
pub session_id: String,
pub agent: Option<String>,
pub strategy: Option<String>,
}
pub fn pick_session() -> Result<(Session, Option<InspectSwap>)> {
let derived = Session::open_readonly()?;
let derived_reads: i64 = derived
.conn
.query_row(
"SELECT COUNT(*) FROM reads WHERE session_id = ?1",
params![derived.id],
|r| r.get(0),
)
.unwrap_or(0);
let Some(cwd) = std::env::current_dir()
.ok()
.and_then(|p| p.canonicalize().ok())
.map(|p| p.to_string_lossy().into_owned())
else {
return Ok((derived, None));
};
if derived.strategy == SessionStrategy::Env && derived_reads > 0 {
return Ok((derived, None));
}
let best: Option<(String, Option<String>, Option<String>, i64)> = derived
.conn
.query_row(
"SELECT s.session_id, s.agent, s.strategy,
(SELECT COUNT(*) FROM reads r WHERE r.session_id = s.session_id) AS reads
FROM sessions s
WHERE s.cwd = ?1
ORDER BY (CASE WHEN s.strategy = 'env' THEN 0 ELSE 1 END),
s.last_active DESC
LIMIT 1",
params![cwd],
|r| Ok((r.get(0)?, r.get(1)?, r.get(2)?, r.get(3)?)),
)
.optional()
.unwrap_or(None);
let Some((id, agent, strategy, reads)) = best else {
return Ok((derived, None));
};
if id == derived.id || reads == 0 {
return Ok((derived, None));
}
let session = Session::open_with_id_readonly(id.clone())?;
Ok((
session,
Some(InspectSwap {
session_id: id,
agent,
strategy,
}),
))
}
pub fn pretty_agent(tag: Option<String>) -> Option<String> {
tag.map(|t| match t.as_str() {
"claude" => "Claude Code".to_string(),
"codex" => "Codex".to_string(),
"gemini" => "Gemini".to_string(),
other => other.to_string(),
})
}