/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "refs.h"
#include "hash.h"
#include "repository.h"
#include "fileops.h"
#include "filebuf.h"
#include "pack.h"
#include "reflog.h"
#include "refdb.h"

#include <git2/tag.h>
#include <git2/object.h>
#include <git2/oid.h>
#include <git2/branch.h>
#include <git2/refs.h>
#include <git2/refdb.h>
#include <git2/sys/refs.h>
#include <git2/signature.h>
#include <git2/commit.h>

bool git_reference__enable_symbolic_ref_target_validation = true;

#define DEFAULT_NESTING_LEVEL	5
#define MAX_NESTING_LEVEL		10

enum {
	GIT_PACKREF_HAS_PEEL = 1,
	GIT_PACKREF_WAS_LOOSE = 2
};

static git_reference *alloc_ref(const char *name)
{
	git_reference *ref = NULL;
	size_t namelen = strlen(name), reflen;

	if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
		!GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
		(ref = git__calloc(1, reflen)) != NULL)
		memcpy(ref->name, name, namelen + 1);

	return ref;
}

git_reference *git_reference__alloc_symbolic(
	const char *name, const char *target)
{
	git_reference *ref;

	assert(name && target);

	ref = alloc_ref(name);
	if (!ref)
		return NULL;

	ref->type = GIT_REF_SYMBOLIC;

	if ((ref->target.symbolic = git__strdup(target)) == NULL) {
		git__free(ref);
		return NULL;
	}

	return ref;
}

git_reference *git_reference__alloc(
	const char *name,
	const git_oid *oid,
	const git_oid *peel)
{
	git_reference *ref;

	assert(name && oid);

	ref = alloc_ref(name);
	if (!ref)
		return NULL;

	ref->type = GIT_REF_OID;
	git_oid_cpy(&ref->target.oid, oid);

	if (peel != NULL)
		git_oid_cpy(&ref->peel, peel);

	return ref;
}

git_reference *git_reference__set_name(
	git_reference *ref, const char *name)
{
	size_t namelen = strlen(name);
	size_t reflen;
	git_reference *rewrite = NULL;

	if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
		!GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
		(rewrite = git__realloc(ref, reflen)) != NULL)
		memcpy(rewrite->name, name, namelen + 1);

	return rewrite;
}

int git_reference_dup(git_reference **dest, git_reference *source)
{
	if (source->type == GIT_REF_SYMBOLIC)
		*dest = git_reference__alloc_symbolic(source->name, source->target.symbolic);
	else
		*dest = git_reference__alloc(source->name, &source->target.oid, &source->peel);

	GITERR_CHECK_ALLOC(*dest);

	return 0;
}

void git_reference_free(git_reference *reference)
{
	if (reference == NULL)
		return;

	if (reference->type == GIT_REF_SYMBOLIC)
		git__free(reference->target.symbolic);

	if (reference->db)
		GIT_REFCOUNT_DEC(reference->db, git_refdb__free);

	git__free(reference);
}

int git_reference_delete(git_reference *ref)
{
	const git_oid *old_id = NULL;
	const char *old_target = NULL;

	if (ref->type == GIT_REF_OID)
		old_id = &ref->target.oid;
	else
		old_target = ref->target.symbolic;

	return git_refdb_delete(ref->db, ref->name, old_id, old_target);
}

int git_reference_remove(git_repository *repo, const char *name)
{
	git_refdb *db;
	int error;

	if ((error = git_repository_refdb__weakptr(&db, repo)) < 0)
		return error;

	return git_refdb_delete(db, name, NULL, NULL);
}

int git_reference_lookup(git_reference **ref_out,
	git_repository *repo, const char *name)
{
	return git_reference_lookup_resolved(ref_out, repo, name, 0);
}

int git_reference_name_to_id(
	git_oid *out, git_repository *repo, const char *name)
{
	int error;
	git_reference *ref;

	if ((error = git_reference_lookup_resolved(&ref, repo, name, -1)) < 0)
		return error;

	git_oid_cpy(out, git_reference_target(ref));
	git_reference_free(ref);
	return 0;
}

static int reference_normalize_for_repo(
	git_refname_t out,
	git_repository *repo,
	const char *name,
	bool validate)
{
	int precompose;
	unsigned int flags = GIT_REF_FORMAT_ALLOW_ONELEVEL;

	if (!git_repository__cvar(&precompose, repo, GIT_CVAR_PRECOMPOSE) &&
		precompose)
		flags |= GIT_REF_FORMAT__PRECOMPOSE_UNICODE;

	if (!validate)
		flags |= GIT_REF_FORMAT__VALIDATION_DISABLE;

	return git_reference_normalize_name(out, GIT_REFNAME_MAX, name, flags);
}

int git_reference_lookup_resolved(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	int max_nesting)
{
	git_refname_t scan_name;
	git_ref_t scan_type;
	int error = 0, nesting;
	git_reference *ref = NULL;
	git_refdb *refdb;

	assert(ref_out && repo && name);

	*ref_out = NULL;

	if (max_nesting > MAX_NESTING_LEVEL)
		max_nesting = MAX_NESTING_LEVEL;
	else if (max_nesting < 0)
		max_nesting = DEFAULT_NESTING_LEVEL;

	scan_type = GIT_REF_SYMBOLIC;

	if ((error = reference_normalize_for_repo(scan_name, repo, name, true)) < 0)
		return error;

	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
		return error;

	for (nesting = max_nesting;
		 nesting >= 0 && scan_type == GIT_REF_SYMBOLIC;
		 nesting--)
	{
		if (nesting != max_nesting) {
			strncpy(scan_name, ref->target.symbolic, sizeof(scan_name));
			git_reference_free(ref);
		}

		if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0)
			return error;

		scan_type = ref->type;
	}

	if (scan_type != GIT_REF_OID && max_nesting != 0) {
		giterr_set(GITERR_REFERENCE,
			"cannot resolve reference (>%u levels deep)", max_nesting);
		git_reference_free(ref);
		return -1;
	}

	*ref_out = ref;
	return 0;
}

int git_reference__read_head(
	git_reference **out,
	git_repository *repo,
	const char *path)
{
	git_buf reference = GIT_BUF_INIT;
	char *name = NULL;
	int error;

	if ((error = git_futils_readbuffer(&reference, path)) < 0)
		goto out;
	git_buf_rtrim(&reference);

	if (git__strncmp(reference.ptr, GIT_SYMREF, strlen(GIT_SYMREF)) == 0) {
		git_buf_consume(&reference, reference.ptr + strlen(GIT_SYMREF));

		name = git_path_basename(path);

		if ((*out = git_reference__alloc_symbolic(name, reference.ptr)) == NULL) {
			error = -1;
			goto out;
		}
	} else {
		if ((error = git_reference_lookup(out, repo, reference.ptr)) < 0)
			goto out;
	}

out:
	git__free(name);
	git_buf_free(&reference);

	return error;
}

int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname)
{
	int error = 0, i;
	bool fallbackmode = true, foundvalid = false;
	git_reference *ref;
	git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT;

	static const char* formatters[] = {
		"%s",
		GIT_REFS_DIR "%s",
		GIT_REFS_TAGS_DIR "%s",
		GIT_REFS_HEADS_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s",
		GIT_REFS_REMOTES_DIR "%s/" GIT_HEAD_FILE,
		NULL
	};

	if (*refname)
		git_buf_puts(&name, refname);
	else {
		git_buf_puts(&name, GIT_HEAD_FILE);
		fallbackmode = false;
	}

	for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) {

		git_buf_clear(&refnamebuf);

		if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0)
			goto cleanup;

		if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
			error = GIT_EINVALIDSPEC;
			continue;
		}
		foundvalid = true;

		error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1);

		if (!error) {
			*out = ref;
			error = 0;
			goto cleanup;
		}

		if (error != GIT_ENOTFOUND)
			goto cleanup;
	}

cleanup:
	if (error && !foundvalid) {
		/* never found a valid reference name */
		giterr_set(GITERR_REFERENCE,
			"could not use '%s' as valid reference name", git_buf_cstr(&name));
	}

	if (error == GIT_ENOTFOUND)
		giterr_set(GITERR_REFERENCE, "no reference found for shorthand '%s'", refname);

	git_buf_free(&name);
	git_buf_free(&refnamebuf);
	return error;
}

/**
 * Getters
 */
git_ref_t git_reference_type(const git_reference *ref)
{
	assert(ref);
	return ref->type;
}

const char *git_reference_name(const git_reference *ref)
{
	assert(ref);
	return ref->name;
}

git_repository *git_reference_owner(const git_reference *ref)
{
	assert(ref);
	return ref->db->repo;
}

const git_oid *git_reference_target(const git_reference *ref)
{
	assert(ref);

	if (ref->type != GIT_REF_OID)
		return NULL;

	return &ref->target.oid;
}

const git_oid *git_reference_target_peel(const git_reference *ref)
{
	assert(ref);

	if (ref->type != GIT_REF_OID || git_oid_iszero(&ref->peel))
		return NULL;

	return &ref->peel;
}

const char *git_reference_symbolic_target(const git_reference *ref)
{
	assert(ref);

	if (ref->type != GIT_REF_SYMBOLIC)
		return NULL;

	return ref->target.symbolic;
}

static int reference__create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *oid,
	const char *symbolic,
	int force,
	const git_signature *signature,
	const char *log_message,
	const git_oid *old_id,
	const char *old_target)
{
	git_refname_t normalized;
	git_refdb *refdb;
	git_reference *ref = NULL;
	int error = 0;

	assert(repo && name);
	assert(symbolic || signature);

	if (ref_out)
		*ref_out = NULL;

	error = reference_normalize_for_repo(normalized, repo, name, true);
	if (error < 0)
		return error;

	error = git_repository_refdb__weakptr(&refdb, repo);
	if (error < 0)
		return error;

	if (oid != NULL) {
		assert(symbolic == NULL);

		if (!git_object__is_valid(repo, oid, GIT_OBJ_ANY)) {
			giterr_set(GITERR_REFERENCE,
				"target OID for the reference doesn't exist on the repository");
			return -1;
		}

		ref = git_reference__alloc(normalized, oid, NULL);
	} else {
		git_refname_t normalized_target;

		error = reference_normalize_for_repo(normalized_target, repo,
			symbolic, git_reference__enable_symbolic_ref_target_validation);

		if (error < 0)
			return error;

		ref = git_reference__alloc_symbolic(normalized, normalized_target);
	}

	GITERR_CHECK_ALLOC(ref);

	if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) {
		git_reference_free(ref);
		return error;
	}

	if (ref_out == NULL)
		git_reference_free(ref);
	else
		*ref_out = ref;

	return 0;
}

int configured_ident(git_signature **out, const git_repository *repo)
{
	if (repo->ident_name && repo->ident_email)
		return git_signature_now(out, repo->ident_name, repo->ident_email);

	/* if not configured let us fall-through to the next method  */
	return -1;
}

int git_reference__log_signature(git_signature **out, git_repository *repo)
{
	int error;
	git_signature *who;

	if(((error = configured_ident(&who, repo)) < 0) &&
	   ((error = git_signature_default(&who, repo)) < 0) &&
	   ((error = git_signature_now(&who, "unknown", "unknown")) < 0))
		return error;

	*out = who;
	return 0;
}

int git_reference_create_matching(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *id,
	int force,
	const git_oid *old_id,
	const char *log_message)

{
	int error;
	git_signature *who = NULL;

	assert(id);

	if ((error = git_reference__log_signature(&who, repo)) < 0)
		return error;

	error = reference__create(
		ref_out, repo, name, id, NULL, force, who, log_message, old_id, NULL);

	git_signature_free(who);
	return error;
}

int git_reference_create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *id,
	int force,
	const char *log_message)
{
        return git_reference_create_matching(ref_out, repo, name, id, force, NULL, log_message);
}

int git_reference_symbolic_create_matching(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const char *target,
	int force,
	const char *old_target,
	const char *log_message)
{
	int error;
	git_signature *who = NULL;

	assert(target);

	if ((error = git_reference__log_signature(&who, repo)) < 0)
		return error;

	error = reference__create(
		ref_out, repo, name, NULL, target, force, who, log_message, NULL, old_target);

	git_signature_free(who);
	return error;
}

int git_reference_symbolic_create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const char *target,
	int force,
	const char *log_message)
{
	return git_reference_symbolic_create_matching(ref_out, repo, name, target, force, NULL, log_message);
}

static int ensure_is_an_updatable_direct_reference(git_reference *ref)
{
	if (ref->type == GIT_REF_OID)
		return 0;

	giterr_set(GITERR_REFERENCE, "cannot set OID on symbolic reference");
	return -1;
}

int git_reference_set_target(
	git_reference **out,
	git_reference *ref,
	const git_oid *id,
	const char *log_message)
{
	int error;
	git_repository *repo;

	assert(out && ref && id);

	repo = ref->db->repo;

	if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0)
		return error;

	return git_reference_create_matching(out, repo, ref->name, id, 1, &ref->target.oid, log_message);
}

static int ensure_is_an_updatable_symbolic_reference(git_reference *ref)
{
	if (ref->type == GIT_REF_SYMBOLIC)
		return 0;

	giterr_set(GITERR_REFERENCE, "cannot set symbolic target on a direct reference");
	return -1;
}

int git_reference_symbolic_set_target(
	git_reference **out,
	git_reference *ref,
	const char *target,
	const char *log_message)
{
	int error;

	assert(out && ref && target);

	if ((error = ensure_is_an_updatable_symbolic_reference(ref)) < 0)
		return error;

	return git_reference_symbolic_create_matching(
		out, ref->db->repo, ref->name, target, 1, ref->target.symbolic, log_message);
}

typedef struct {
    const char *old_name;
    git_refname_t new_name;
} rename_cb_data;

static int update_wt_heads(git_repository *repo, const char *path, void *payload)
{
	rename_cb_data *data = (rename_cb_data *) payload;
	git_reference *head;
	char *gitdir = NULL;
	int error = 0;

	if (git_reference__read_head(&head, repo, path) < 0 ||
	    git_reference_type(head) != GIT_REF_SYMBOLIC ||
	    git__strcmp(head->target.symbolic, data->old_name) != 0 ||
	    (gitdir = git_path_dirname(path)) == NULL)
		goto out;

	/* Update HEAD it was pointing to the reference being renamed */
	if ((error = git_repository_create_head(gitdir, data->new_name)) < 0) {
		giterr_set(GITERR_REFERENCE, "failed to update HEAD after renaming reference");
		goto out;
	}

out:
	git_reference_free(head);
	git__free(gitdir);

	return error;
}

static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force,
				 const git_signature *signature, const char *message)
{
	git_repository *repo;
	git_refname_t normalized;
	bool should_head_be_updated = false;
	int error = 0;

	assert(ref && new_name && signature);

	repo = git_reference_owner(ref);

	if ((error = reference_normalize_for_repo(
		normalized, repo, new_name, true)) < 0)
		return error;

	/* Check if we have to update HEAD. */
	if ((error = git_branch_is_head(ref)) < 0)
		return error;

	should_head_be_updated = (error > 0);

	if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0)
		return error;

	/* Update HEAD if it was pointing to the reference being renamed */
	if (should_head_be_updated) {
		error = git_repository_set_head(ref->db->repo, normalized);
	} else {
		rename_cb_data payload;
		payload.old_name = ref->name;
		memcpy(&payload.new_name, &normalized, sizeof(normalized));

		error = git_repository_foreach_head(repo, update_wt_heads, &payload);
	}

	return error;
}


int git_reference_rename(
	git_reference **out,
	git_reference *ref,
	const char *new_name,
	int force,
	const char *log_message)
{
	git_signature *who;
	int error;

	if ((error = git_reference__log_signature(&who, ref->db->repo)) < 0)
		return error;

	error = reference__rename(out, ref, new_name, force, who, log_message);
	git_signature_free(who);

	return error;
}

int git_reference_resolve(git_reference **ref_out, const git_reference *ref)
{
	switch (git_reference_type(ref)) {
	case GIT_REF_OID:
		return git_reference_lookup(ref_out, ref->db->repo, ref->name);

	case GIT_REF_SYMBOLIC:
		return git_reference_lookup_resolved(ref_out, ref->db->repo, ref->target.symbolic, -1);

	default:
		giterr_set(GITERR_REFERENCE, "invalid reference");
		return -1;
	}
}

int git_reference_foreach(
	git_repository *repo,
	git_reference_foreach_cb callback,
	void *payload)
{
	git_reference_iterator *iter;
	git_reference *ref;
	int error;

	if ((error = git_reference_iterator_new(&iter, repo)) < 0)
		return error;

	while (!(error = git_reference_next(&ref, iter))) {
		if ((error = callback(ref, payload)) != 0) {
			giterr_set_after_callback(error);
			break;
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_reference_iterator_free(iter);
	return error;
}

int git_reference_foreach_name(
	git_repository *repo,
	git_reference_foreach_name_cb callback,
	void *payload)
{
	git_reference_iterator *iter;
	const char *refname;
	int error;

	if ((error = git_reference_iterator_new(&iter, repo)) < 0)
		return error;

	while (!(error = git_reference_next_name(&refname, iter))) {
		if ((error = callback(refname, payload)) != 0) {
			giterr_set_after_callback(error);
			break;
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_reference_iterator_free(iter);
	return error;
}

int git_reference_foreach_glob(
	git_repository *repo,
	const char *glob,
	git_reference_foreach_name_cb callback,
	void *payload)
{
	git_reference_iterator *iter;
	const char *refname;
	int error;

	if ((error = git_reference_iterator_glob_new(&iter, repo, glob)) < 0)
		return error;

	while (!(error = git_reference_next_name(&refname, iter))) {
		if ((error = callback(refname, payload)) != 0) {
			giterr_set_after_callback(error);
			break;
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_reference_iterator_free(iter);
	return error;
}

int git_reference_iterator_new(git_reference_iterator **out, git_repository *repo)
{
	git_refdb *refdb;

	if (git_repository_refdb__weakptr(&refdb, repo) < 0)
		return -1;

	return git_refdb_iterator(out, refdb, NULL);
}

int git_reference_iterator_glob_new(
	git_reference_iterator **out, git_repository *repo, const char *glob)
{
	git_refdb *refdb;

	if (git_repository_refdb__weakptr(&refdb, repo) < 0)
		return -1;

	return git_refdb_iterator(out, refdb, glob);
}

int git_reference_next(git_reference **out, git_reference_iterator *iter)
{
	return git_refdb_iterator_next(out, iter);
}

int git_reference_next_name(const char **out, git_reference_iterator *iter)
{
	return git_refdb_iterator_next_name(out, iter);
}

void git_reference_iterator_free(git_reference_iterator *iter)
{
	if (iter == NULL)
		return;

	git_refdb_iterator_free(iter);
}

static int cb__reflist_add(const char *ref, void *data)
{
	char *name = git__strdup(ref);
	GITERR_CHECK_ALLOC(name);
	return git_vector_insert((git_vector *)data, name);
}

int git_reference_list(
	git_strarray *array,
	git_repository *repo)
{
	git_vector ref_list;

	assert(array && repo);

	array->strings = NULL;
	array->count = 0;

	if (git_vector_init(&ref_list, 8, NULL) < 0)
		return -1;

	if (git_reference_foreach_name(
			repo, &cb__reflist_add, (void *)&ref_list) < 0) {
		git_vector_free(&ref_list);
		return -1;
	}

	array->strings = (char **)git_vector_detach(&array->count, NULL, &ref_list);

	return 0;
}

static int is_valid_ref_char(char ch)
{
	if ((unsigned) ch <= ' ')
		return 0;

	switch (ch) {
	case '~':
	case '^':
	case ':':
	case '\\':
	case '?':
	case '[':
	case '*':
		return 0;
	default:
		return 1;
	}
}

static int ensure_segment_validity(const char *name)
{
	const char *current = name;
	char prev = '\0';
	const int lock_len = (int)strlen(GIT_FILELOCK_EXTENSION);
	int segment_len;

	if (*current == '.')
		return -1; /* Refname starts with "." */

	for (current = name; ; current++) {
		if (*current == '\0' || *current == '/')
			break;

		if (!is_valid_ref_char(*current))
			return -1; /* Illegal character in refname */

		if (prev == '.' && *current == '.')
			return -1; /* Refname contains ".." */

		if (prev == '@' && *current == '{')
			return -1; /* Refname contains "@{" */

		prev = *current;
	}

	segment_len = (int)(current - name);

	/* A refname component can not end with ".lock" */
	if (segment_len >= lock_len &&
		!memcmp(current - lock_len, GIT_FILELOCK_EXTENSION, lock_len))
			return -1;

	return segment_len;
}

static bool is_all_caps_and_underscore(const char *name, size_t len)
{
	size_t i;
	char c;

	assert(name && len > 0);

	for (i = 0; i < len; i++)
	{
		c = name[i];
		if ((c < 'A' || c > 'Z') && c != '_')
			return false;
	}

	if (*name == '_' || name[len - 1] == '_')
		return false;

	return true;
}

/* Inspired from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/refs.c#L36-100 */
int git_reference__normalize_name(
	git_buf *buf,
	const char *name,
	unsigned int flags)
{
	const char *current;
	int segment_len, segments_count = 0, error = GIT_EINVALIDSPEC;
	unsigned int process_flags;
	bool normalize = (buf != NULL);
	bool validate = (flags & GIT_REF_FORMAT__VALIDATION_DISABLE) == 0;

#ifdef GIT_USE_ICONV
	git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
#endif

	assert(name);

	process_flags = flags;
	current = (char *)name;

	if (validate && *current == '/')
		goto cleanup;

	if (normalize)
		git_buf_clear(buf);

#ifdef GIT_USE_ICONV
	if ((flags & GIT_REF_FORMAT__PRECOMPOSE_UNICODE) != 0) {
		size_t namelen = strlen(current);
		if ((error = git_path_iconv_init_precompose(&ic)) < 0 ||
			(error = git_path_iconv(&ic, &current, &namelen)) < 0)
			goto cleanup;
		error = GIT_EINVALIDSPEC;
	}
#endif

	if (!validate) {
		git_buf_sets(buf, current);

		error = git_buf_oom(buf) ? -1 : 0;
		goto cleanup;
	}

	while (true) {
		segment_len = ensure_segment_validity(current);
		if (segment_len < 0) {
			if ((process_flags & GIT_REF_FORMAT_REFSPEC_PATTERN) &&
					current[0] == '*' &&
					(current[1] == '\0' || current[1] == '/')) {
				/* Accept one wildcard as a full refname component. */
				process_flags &= ~GIT_REF_FORMAT_REFSPEC_PATTERN;
				segment_len = 1;
			} else
				goto cleanup;
		}

		if (segment_len > 0) {
			if (normalize) {
				size_t cur_len = git_buf_len(buf);

				git_buf_joinpath(buf, git_buf_cstr(buf), current);
				git_buf_truncate(buf,
					cur_len + segment_len + (segments_count ? 1 : 0));

				if (git_buf_oom(buf)) {
					error = -1;
					goto cleanup;
				}
			}

			segments_count++;
		}

		/* No empty segment is allowed when not normalizing */
		if (segment_len == 0 && !normalize)
			goto cleanup;

		if (current[segment_len] == '\0')
			break;

		current += segment_len + 1;
	}

	/* A refname can not be empty */
	if (segment_len == 0 && segments_count == 0)
		goto cleanup;

	/* A refname can not end with "." */
	if (current[segment_len - 1] == '.')
		goto cleanup;

	/* A refname can not end with "/" */
	if (current[segment_len - 1] == '/')
		goto cleanup;

	if ((segments_count == 1 ) && !(flags & GIT_REF_FORMAT_ALLOW_ONELEVEL))
		goto cleanup;

	if ((segments_count == 1 ) &&
	    !(flags & GIT_REF_FORMAT_REFSPEC_SHORTHAND) &&
		!(is_all_caps_and_underscore(name, (size_t)segment_len) ||
			((flags & GIT_REF_FORMAT_REFSPEC_PATTERN) && !strcmp("*", name))))
			goto cleanup;

	if ((segments_count > 1)
		&& (is_all_caps_and_underscore(name, strchr(name, '/') - name)))
			goto cleanup;

	error = 0;

cleanup:
	if (error == GIT_EINVALIDSPEC)
		giterr_set(
			GITERR_REFERENCE,
			"the given reference name '%s' is not valid", name);

	if (error && normalize)
		git_buf_free(buf);

#ifdef GIT_USE_ICONV
	git_path_iconv_clear(&ic);
#endif

	return error;
}

int git_reference_normalize_name(
	char *buffer_out,
	size_t buffer_size,
	const char *name,
	unsigned int flags)
{
	git_buf buf = GIT_BUF_INIT;
	int error;

	if ((error = git_reference__normalize_name(&buf, name, flags)) < 0)
		goto cleanup;

	if (git_buf_len(&buf) > buffer_size - 1) {
		giterr_set(
		GITERR_REFERENCE,
		"the provided buffer is too short to hold the normalization of '%s'", name);
		error = GIT_EBUFS;
		goto cleanup;
	}

	git_buf_copy_cstr(buffer_out, buffer_size, &buf);

	error = 0;

cleanup:
	git_buf_free(&buf);
	return error;
}

#define GIT_REF_TYPEMASK (GIT_REF_OID | GIT_REF_SYMBOLIC)

int git_reference_cmp(
	const git_reference *ref1,
	const git_reference *ref2)
{
	git_ref_t type1, type2;
	assert(ref1 && ref2);

	type1 = git_reference_type(ref1);
	type2 = git_reference_type(ref2);

	/* let's put symbolic refs before OIDs */
	if (type1 != type2)
		return (type1 == GIT_REF_SYMBOLIC) ? -1 : 1;

	if (type1 == GIT_REF_SYMBOLIC)
		return strcmp(ref1->target.symbolic, ref2->target.symbolic);

	return git_oid__cmp(&ref1->target.oid, &ref2->target.oid);
}

/**
 * Get the end of a chain of references. If the final one is not
 * found, we return the reference just before that.
 */
static int get_terminal(git_reference **out, git_repository *repo, const char *ref_name, int nesting)
{
	git_reference *ref;
	int error = 0;

	if (nesting > MAX_NESTING_LEVEL) {
		giterr_set(GITERR_REFERENCE, "reference chain too deep (%d)", nesting);
		return GIT_ENOTFOUND;
	}

	/* set to NULL to let the caller know that they're at the end of the chain */
	if ((error = git_reference_lookup(&ref, repo, ref_name)) < 0) {
		*out = NULL;
		return error;
	}

	if (git_reference_type(ref) == GIT_REF_OID) {
		*out = ref;
		error = 0;
	} else {
		error = get_terminal(out, repo, git_reference_symbolic_target(ref), nesting + 1);
		if (error == GIT_ENOTFOUND && !*out)
			*out = ref;
		else
			git_reference_free(ref);
	}

	return error;
}

/*
 * Starting with the reference given by `ref_name`, follows symbolic
 * references until a direct reference is found and updated the OID
 * on that direct reference to `oid`.
 */
int git_reference__update_terminal(
	git_repository *repo,
	const char *ref_name,
	const git_oid *oid,
	const git_signature *sig,
	const char *log_message)
{
	git_reference *ref = NULL, *ref2 = NULL;
	git_signature *who = NULL;
	const git_signature *to_use;
	int error = 0;

	if (!sig && (error = git_reference__log_signature(&who, repo)) < 0)
		return error;

	to_use = sig ? sig : who;
	error = get_terminal(&ref, repo, ref_name, 0);

	/* found a dangling symref */
	if (error == GIT_ENOTFOUND && ref) {
		assert(git_reference_type(ref) == GIT_REF_SYMBOLIC);
		giterr_clear();
		error = reference__create(&ref2, repo, ref->target.symbolic, oid, NULL, 0, to_use,
					  log_message, NULL, NULL);
	} else if (error == GIT_ENOTFOUND) {
		giterr_clear();
		error = reference__create(&ref2, repo, ref_name, oid, NULL, 0, to_use,
					  log_message, NULL, NULL);
	}  else if (error == 0) {
		assert(git_reference_type(ref) == GIT_REF_OID);
		error = reference__create(&ref2, repo, ref->name, oid, NULL, 1, to_use,
					  log_message, &ref->target.oid, NULL);
	}

	git_reference_free(ref2);
	git_reference_free(ref);
	git_signature_free(who);
	return error;
}

static const char *commit_type(const git_commit *commit)
{
	unsigned int count = git_commit_parentcount(commit);

	if (count >= 2)
		return " (merge)";
	else if (count == 0)
		return " (initial)";
	else
		return "";
}

int git_reference__update_for_commit(
	git_repository *repo,
	git_reference *ref,
	const char *ref_name,
	const git_oid *id,
	const char *operation)
{
	git_reference *ref_new = NULL;
	git_commit *commit = NULL;
	git_buf reflog_msg = GIT_BUF_INIT;
	const git_signature *who;
	int error;

	if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
		(error = git_buf_printf(&reflog_msg, "%s%s: %s",
			operation ? operation : "commit",
			commit_type(commit),
			git_commit_summary(commit))) < 0)
		goto done;

	who = git_commit_committer(commit);

	if (ref) {
		if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0)
			return error;

		error = reference__create(&ref_new, repo, ref->name, id, NULL, 1, who,
					  git_buf_cstr(&reflog_msg), &ref->target.oid, NULL);
	}
	else
		error = git_reference__update_terminal(
			repo, ref_name, id, who, git_buf_cstr(&reflog_msg));

done:
	git_reference_free(ref_new);
	git_buf_free(&reflog_msg);
	git_commit_free(commit);
	return error;
}

int git_reference_has_log(git_repository *repo, const char *refname)
{
	int error;
	git_refdb *refdb;

	assert(repo && refname);

	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
		return error;

	return git_refdb_has_log(refdb, refname);
}

int git_reference_ensure_log(git_repository *repo, const char *refname)
{
	int error;
	git_refdb *refdb;

	assert(repo && refname);

	if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
		return error;

	return git_refdb_ensure_log(refdb, refname);
}

int git_reference__is_branch(const char *ref_name)
{
	return git__prefixcmp(ref_name, GIT_REFS_HEADS_DIR) == 0;
}

int git_reference_is_branch(const git_reference *ref)
{
	assert(ref);
	return git_reference__is_branch(ref->name);
}

int git_reference__is_remote(const char *ref_name)
{
	return git__prefixcmp(ref_name, GIT_REFS_REMOTES_DIR) == 0;
}

int git_reference_is_remote(const git_reference *ref)
{
	assert(ref);
	return git_reference__is_remote(ref->name);
}

int git_reference__is_tag(const char *ref_name)
{
	return git__prefixcmp(ref_name, GIT_REFS_TAGS_DIR) == 0;
}

int git_reference_is_tag(const git_reference *ref)
{
	assert(ref);
	return git_reference__is_tag(ref->name);
}

int git_reference__is_note(const char *ref_name)
{
	return git__prefixcmp(ref_name, GIT_REFS_NOTES_DIR) == 0;
}

int git_reference_is_note(const git_reference *ref)
{
	assert(ref);
	return git_reference__is_note(ref->name);
}

static int peel_error(int error, git_reference *ref, const char* msg)
{
	giterr_set(
		GITERR_INVALID,
		"the reference '%s' cannot be peeled - %s", git_reference_name(ref), msg);
	return error;
}

int git_reference_peel(
	git_object **peeled,
	git_reference *ref,
	git_otype target_type)
{
	git_reference *resolved = NULL;
	git_object *target = NULL;
	int error;

	assert(ref);

	if (ref->type == GIT_REF_OID) {
		resolved = ref;
	} else {
		if ((error = git_reference_resolve(&resolved, ref)) < 0)
			return peel_error(error, ref, "Cannot resolve reference");
	}

	if (!git_oid_iszero(&resolved->peel)) {
		error = git_object_lookup(&target,
			git_reference_owner(ref), &resolved->peel, GIT_OBJ_ANY);
	} else {
		error = git_object_lookup(&target,
			git_reference_owner(ref), &resolved->target.oid, GIT_OBJ_ANY);
	}

	if (error < 0) {
		peel_error(error, ref, "Cannot retrieve reference target");
		goto cleanup;
	}

	if (target_type == GIT_OBJ_ANY && git_object_type(target) != GIT_OBJ_TAG)
		error = git_object_dup(peeled, target);
	else
		error = git_object_peel(peeled, target, target_type);

cleanup:
	git_object_free(target);

	if (resolved != ref)
		git_reference_free(resolved);

	return error;
}

int git_reference__is_valid_name(const char *refname, unsigned int flags)
{
	if (git_reference__normalize_name(NULL, refname, flags) < 0) {
		giterr_clear();
		return false;
	}

	return true;
}

int git_reference_is_valid_name(const char *refname)
{
	return git_reference__is_valid_name(refname, GIT_REF_FORMAT_ALLOW_ONELEVEL);
}

const char *git_reference__shorthand(const char *name)
{
	if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR))
		return name + strlen(GIT_REFS_HEADS_DIR);
	else if (!git__prefixcmp(name, GIT_REFS_TAGS_DIR))
		return name + strlen(GIT_REFS_TAGS_DIR);
	else if (!git__prefixcmp(name, GIT_REFS_REMOTES_DIR))
		return name + strlen(GIT_REFS_REMOTES_DIR);
	else if (!git__prefixcmp(name, GIT_REFS_DIR))
		return name + strlen(GIT_REFS_DIR);

	/* No shorthands are avaiable, so just return the name */
	return name;
}

const char *git_reference_shorthand(const git_reference *ref)
{
	return git_reference__shorthand(ref->name);
}
