//! GitState computation from GitRunner output.
//!
//! Aggregates branch, status, remotes, and worktrees into a single
//! `GitState` struct with graceful degradation via `GitWarning`.

use crate::git::runner::GitRunner;
use dirigent_protocol::project::{GitState, GitWarning, WorktreeInfo};

/// Compute the full git state for a repository.
///
/// Calls branch, status, remotes, and worktree_list. Any individual
/// failure is captured as a `GitWarning` rather than failing the whole
/// computation.
pub async fn compute_git_state(runner: &GitRunner) -> GitState {
    let mut state = GitState::default();
    let mut warnings = Vec::new();

    // Status (includes branch + dirty + ahead/behind)
    match runner.status().await {
        Ok(status) => {
            state.branch = status.branch;
            state.is_dirty = status.is_dirty;
            state.ahead = status.ahead;
            state.behind = status.behind;
        }
        Err(e) => {
            warnings.push(GitWarning {
                code: "status_failed".to_string(),
                message: format!("Failed to get git status: {e}"),
            });
            // Try branch separately as fallback
            match runner.current_branch().await {
                Ok(branch) => state.branch = branch,
                Err(e) => {
                    warnings.push(GitWarning {
                        code: "branch_failed".to_string(),
                        message: format!("Failed to get current branch: {e}"),
                    });
                }
            }
        }
    }

    // Remotes
    match runner.remotes().await {
        Ok(remotes) => state.remotes = remotes,
        Err(e) => {
            warnings.push(GitWarning {
                code: "remotes_failed".to_string(),
                message: format!("Failed to list remotes: {e}"),
            });
        }
    }

    // Worktrees
    match runner.worktree_list().await {
        Ok(entries) => {
            state.worktrees = entries
                .into_iter()
                .map(|e| WorktreeInfo {
                    path: e.path,
                    branch: e.branch,
                    is_detached: e.is_detached,
                })
                .collect();
        }
        Err(e) => {
            warnings.push(GitWarning {
                code: "worktrees_failed".to_string(),
                message: format!("Failed to list worktrees: {e}"),
            });
        }
    }

    state.unexpected = warnings;
    state
}
