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

impl GitBare {
    pub fn commit_refs(&self, oid: ObjectId) -> GitResult<Vec<CommitRefInfo>> {
        let repo = self.gix_repo()?;
        let gix_id: gix::hash::ObjectId = (&oid).try_into()?;
        let target_hex = gix_id.to_hex().to_string();

        let mut refs = Vec::new();

        let platform = repo.references()?;
        let iter = platform.all()?;

        for ref_result in iter {
            let reference = ref_result?;
            let full_name = reference.name().as_bstr().to_string();

            let is_branch = full_name.starts_with("refs/heads/");
            let is_tag = full_name.starts_with("refs/tags/");
            let is_remote = full_name.starts_with("refs/remotes/");

            if !is_branch && !is_tag && !is_remote {
                continue;
            }

            let target = reference.target();
            let target_id = target.try_id().ok_or_else(|| {
                crate::errors::GitError::Internal(
                    "ref has no direct target".to_string(),
                )
            })?;

            if target_id.to_hex().to_string() == target_hex {
                let short_name = reference.name().shorten();
                refs.push(CommitRefInfo {
                    name: short_name.to_string(),
                    target: oid.clone(),
                    is_remote,
                    is_tag,
                });
            }
        }

        Ok(refs)
    }
}
