use std::path::{Path, PathBuf};
use balls::delivery_path::attempt_path;
use balls::layout::Xdg;
use crate::app::Snapshot;
use crate::binding::work_worktree_path;
use crate::fan::Fire;
#[derive(Debug, Clone)]
pub(super) struct Layout {
xdg: Xdg,
balls_state_root: PathBuf,
claimant: String,
}
impl Layout {
pub(super) fn of(xdg: &Xdg, balls_state_root: &Path, claimant: &str) -> Layout {
Layout {
xdg: xdg.clone(),
balls_state_root: balls_state_root.to_path_buf(),
claimant: claimant.to_owned(),
}
}
fn worktrees(&self, attempt: &crate::workdiff::Attempt, repo: &Path) -> Vec<PathBuf> {
match &attempt.handle {
Some(handle) => vec![attempt_path(&self.xdg, &repo.to_string_lossy(), handle)],
None => [None, Some(self.claimant.as_str())]
.into_iter()
.map(|c| work_worktree_path(&self.balls_state_root, repo, &attempt.ball_id, c))
.collect(),
}
}
}
pub(super) fn fire_for(
fires: &[Fire],
attempt: &crate::workdiff::Attempt,
layout: &Layout,
repo: Option<&Path>,
) -> Option<Fire> {
let candidates = layout.worktrees(attempt, repo?);
fires
.iter()
.rev()
.find(|fire| candidates.contains(&fire.worktree))
.cloned()
}
pub(super) fn agent_of(snap: &Snapshot, workspace: &Path, conversation: &str) -> Option<String> {
snap.trees
.get(workspace)?
.agents
.iter()
.find(|a| a.name_fact().as_deref() == Some(conversation))
.map(|a| a.agent_id.clone())
}