//! Agent worktree management — creates and configures git worktrees for agents.
use crate::config::ProjectConfig;
use std::path::{Path, PathBuf};

use super::AgentPool;

impl AgentPool {
    /// Create a worktree for the given story using the server port (writes .mcp.json).
    pub async fn create_worktree(
        &self,
        project_root: &Path,
        story_id: &str,
    ) -> Result<crate::worktree::WorktreeInfo, String> {
        let config = ProjectConfig::load(project_root)?;
        crate::worktree::create_worktree(project_root, story_id, &config, self.port).await
    }

    /// Get project root helper.
    pub fn get_project_root(&self, state: &crate::state::SessionState) -> Result<PathBuf, String> {
        state.get_project_root()
    }
}

/// Return the active pipeline stage for `story_id`, or `None` if the story is not
/// in any active stage (`2_current/`, `3_qa/`, `4_merge/`).
pub(super) fn find_active_story_stage(
    _project_root: &Path,
    story_id: &str,
) -> Option<crate::pipeline_state::Stage> {
    if let Ok(Some(item)) = crate::pipeline_state::read_typed(story_id)
        && matches!(
            item.stage,
            crate::pipeline_state::Stage::Coding { .. }
                | crate::pipeline_state::Stage::Qa
                | crate::pipeline_state::Stage::Merge { .. }
                | crate::pipeline_state::Stage::MergeFailure { .. }
                | crate::pipeline_state::Stage::MergeFailureFinal { .. }
        )
    {
        return Some(item.stage);
    }
    None
}

#[cfg(test)]
mod tests {
    use super::find_active_story_stage;

    #[test]
    fn find_active_story_stage_detects_current() {
        crate::db::ensure_content_store();
        crate::db::write_item_with_content(
            "10_story_test",
            "2_current",
            "---\nname: Test\n---\n",
            crate::db::ItemMeta::named("Test"),
        );
        let tmp = tempfile::tempdir().unwrap();
        assert!(matches!(
            find_active_story_stage(tmp.path(), "10_story_test"),
            Some(crate::pipeline_state::Stage::Coding { .. })
        ));
    }

    #[test]
    fn find_active_story_stage_detects_qa() {
        crate::db::ensure_content_store();
        crate::db::write_item_with_content(
            "11_story_test",
            "3_qa",
            "---\nname: Test\n---\n",
            crate::db::ItemMeta::named("Test"),
        );
        let tmp = tempfile::tempdir().unwrap();
        assert!(matches!(
            find_active_story_stage(tmp.path(), "11_story_test"),
            Some(crate::pipeline_state::Stage::Qa)
        ));
    }

    #[test]
    fn find_active_story_stage_detects_merge() {
        crate::db::ensure_content_store();
        crate::db::write_item_with_content(
            "12_story_test",
            "4_merge",
            "---\nname: Test\n---\n",
            crate::db::ItemMeta::named("Test"),
        );
        let tmp = tempfile::tempdir().unwrap();
        assert!(matches!(
            find_active_story_stage(tmp.path(), "12_story_test"),
            Some(crate::pipeline_state::Stage::Merge { .. })
        ));
    }

    #[test]
    fn find_active_story_stage_returns_none_for_unknown_story() {
        let tmp = tempfile::tempdir().unwrap();
        assert_eq!(find_active_story_stage(tmp.path(), "99_nonexistent"), None);
    }
}
