//! Utilities for working with gix that might be useful for downstream users

use crate::{error::GitError, Error};

/// Writes the `FETCH_HEAD` for the specified fetch outcome to the specified git
/// repository
///
/// This function is narrowly focused on on writing a `FETCH_HEAD` that contains
/// exactly two pieces of information, the id of the commit pointed to by the
/// remote `HEAD`, and, if it exists, the same id with the remote branch whose
/// `HEAD` is the same. This focus gives use two things:
///     1. `FETCH_HEAD` that can be parsed to the correct remote HEAD by
/// [`gix`](https://github.com/Byron/gitoxide/commit/eb2b513bd939f6b59891d0a4cf5465b1c1e458b3)
///     1. A `FETCH_HEAD` that closely (or even exactly) matches that created by
/// cargo via git or git2 when fetching only `+HEAD:refs/remotes/origin/HEAD`
///
/// Calling this function for the fetch outcome of a clone will write `FETCH_HEAD`
/// just as if a normal fetch had occurred, but note that AFAICT neither git nor
/// git2 does this, ie. a fresh clone will not have a `FETCH_HEAD` present. I don't
/// _think_ that has negative implications, but if it does...just don't call this
/// function on the result of a clone :)
///
/// Note that the remote provided should be the same remote used for the fetch
/// operation. The reason this is not just grabbed from the repo is because
/// repositories may not have the configured remote, or the remote was modified
/// (eg. replacing refspecs) before the fetch operation
pub fn write_fetch_head(
    repo: &gix::Repository,
    fetch: &gix::remote::fetch::Outcome,
    remote: &gix::Remote<'_>,
) -> Result<gix::ObjectId, Error> {
    use gix::{bstr::ByteSlice, protocol::handshake::Ref};
    use std::fmt::Write;

    // Find the remote head commit
    let (head_target_branch, oid) = fetch
        .ref_map
        .mappings
        .iter()
        .find_map(|mapping| {
            let gix::remote::fetch::Source::Ref(rref) = &mapping.remote else {
                return None;
            };

            let Ref::Symbolic {
                full_ref_name,
                target,
                object,
                ..
            } = rref
            else {
                return None;
            };

            (full_ref_name == "HEAD").then_some((target, object))
        })
        .ok_or_else(|| GitError::UnableToFindRemoteHead)?;

    let remote_url = {
        let ru = remote
            .url(gix::remote::Direction::Fetch)
            .expect("can't fetch without a fetch url");
        let s = ru.to_bstring();
        let v = s.into();
        String::from_utf8(v).expect("remote url was not utf-8 :-/")
    };

    let fetch_head = {
        let mut hex_id = [0u8; 40];
        let gix::ObjectId::Sha1(sha1) = oid;
        let commit_id = crate::utils::encode_hex(sha1, &mut hex_id);

        let mut fetch_head = String::new();

        let remote_name = remote
            .name()
            .and_then(|n| {
                let gix::remote::Name::Symbol(name) = n else {
                    return None;
                };
                Some(name.as_ref())
            })
            .unwrap_or("origin");

        // We write the remote HEAD first, but _only_ if it was explicitly requested
        if remote
            .refspecs(gix::remote::Direction::Fetch)
            .iter()
            .any(|rspec| {
                let rspec = rspec.to_ref();
                if !rspec.remote().map_or(false, |r| r.ends_with(b"HEAD")) {
                    return false;
                }

                rspec.local().map_or(false, |l| {
                    l.to_str()
                        .ok()
                        .and_then(|l| {
                            l.strip_prefix("refs/remotes/")
                                .and_then(|l| l.strip_suffix("/HEAD"))
                        })
                        .map_or(false, |remote| remote == remote_name)
                })
            })
        {
            writeln!(&mut fetch_head, "{commit_id}\t\t{remote_url}").unwrap();
        }

        // Attempt to get the branch name, but if it looks suspect just skip this,
        // it _should_ be fine, or at least, we've already written the only thing
        // that gix can currently parse
        if let Some(branch_name) = head_target_branch
            .to_str()
            .ok()
            .and_then(|s| s.strip_prefix("refs/heads/"))
        {
            writeln!(
                &mut fetch_head,
                "{commit_id}\t\tbranch '{branch_name}' of {remote_url}"
            )
            .unwrap();
        }

        fetch_head
    };

    // We _could_ also emit other branches/tags like git does, however it's more
    // complicated than just our limited use case of writing remote HEAD
    //
    // 1. Remote branches are always emitted, however in gix those aren't part
    // of the ref mappings if they haven't been updated since the last fetch
    // 2. Conversely, tags are _not_ written by git unless they have been changed
    // added, but gix _does_ always place those in the fetch mappings

    if fetch_head.is_empty() {
        return Err(GitError::UnableToFindRemoteHead.into());
    }

    let fetch_head_path = crate::PathBuf::from_path_buf(repo.path().join("FETCH_HEAD"))?;
    std::fs::write(&fetch_head_path, fetch_head)
        .map_err(|io| Error::IoPath(io, fetch_head_path))?;

    Ok(*oid)
}
