use serde::{Deserialize, Serialize};

use crate::{
    bare::GitBare,
    cmd::{commit::CommitMeta, oid::ObjectId},
    errors::{GitError, GitResult},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommitSummary {
    pub head: Option<CommitMeta>,
    pub count: usize,
}

impl GitBare {
    pub fn commit_summary(&self) -> GitResult<CommitSummary> {
        let repo = self.gix_repo()?;
        let head_id = repo
            .head_id()
            .map_err(|_| GitError::RefNotFound("HEAD".to_string()));
        let head_id = match head_id {
            Ok(id) => id,
            Err(_) => {
                return Ok(CommitSummary {
                    head: None,
                    count: 0,
                });
            }
        };

        let head_oid = ObjectId::new(head_id.detach().to_hex().to_string());
        let head_commit = self.commit_info(head_oid)?;
        let walk = repo.rev_walk([head_id.detach()]).all()?;
        let count = walk.count();

        Ok(CommitSummary {
            head: Some(head_commit),
            count,
        })
    }
}
