/*
 * Copyright (C) 2009-2012 the libgit2 contributors
 *
 * 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 "git2/config.h"
#include "git2/types.h"
#include "git2/oid.h"

#include "config.h"
#include "repository.h"
#include "remote.h"
#include "fetch.h"
#include "refs.h"
#include "refspec.h"
#include "fetchhead.h"

#include <regex.h>

static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const char *var, bool is_fetch)
{
	int error;
	const char *val;

	if ((error = git_config_get_string(&val, cfg, var)) < 0)
		return error;

	return git_refspec__parse(refspec, val, is_fetch);
}

static int download_tags_value(git_remote *remote, git_config *cfg)
{
	const char *val;
	git_buf buf = GIT_BUF_INIT;
	int error;

	if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSET)
		return 0;

	/* This is the default, let's see if we need to change it */
	remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
	if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
		return -1;

	error = git_config_get_string(&val, cfg, git_buf_cstr(&buf));
	git_buf_free(&buf);
	if (!error && !strcmp(val, "--no-tags"))
		remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
	else if (!error && !strcmp(val, "--tags"))
		remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;

	if (error == GIT_ENOTFOUND)
		error = 0;

	return error;
}

int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
{
	git_remote *remote;

	/* name is optional */
	assert(out && repo && url);

	remote = git__malloc(sizeof(git_remote));
	GITERR_CHECK_ALLOC(remote);

	memset(remote, 0x0, sizeof(git_remote));
	remote->repo = repo;
	remote->check_cert = 1;
	remote->update_fetchhead = 1;

	if (git_vector_init(&remote->refs, 32, NULL) < 0)
		return -1;

	remote->url = git__strdup(url);
	GITERR_CHECK_ALLOC(remote->url);

	if (name != NULL) {
		remote->name = git__strdup(name);
		GITERR_CHECK_ALLOC(remote->name);
	}

	if (fetch != NULL) {
		if (git_refspec__parse(&remote->fetch, fetch, true) < 0)
			goto on_error;
	}

	/* A remote without a name doesn't download tags */
	if (!name) {
		remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
	}

	*out = remote;
	return 0;

on_error:
	git_remote_free(remote);
	return -1;
}

int git_remote_load(git_remote **out, git_repository *repo, const char *name)
{
	git_remote *remote;
	git_buf buf = GIT_BUF_INIT;
	const char *val;
	int error = 0;
	git_config *config;

	assert(out && repo && name);

	if (git_repository_config__weakptr(&config, repo) < 0)
		return -1;

	remote = git__malloc(sizeof(git_remote));
	GITERR_CHECK_ALLOC(remote);

	memset(remote, 0x0, sizeof(git_remote));
	remote->check_cert = 1;
	remote->update_fetchhead = 1;
	remote->name = git__strdup(name);
	GITERR_CHECK_ALLOC(remote->name);

	if (git_vector_init(&remote->refs, 32, NULL) < 0) {
		error = -1;
		goto cleanup;
	}

	if (git_buf_printf(&buf, "remote.%s.url", name) < 0) {
		error = -1;
		goto cleanup;
	}

	if ((error = git_config_get_string(&val, config, git_buf_cstr(&buf))) < 0)
		goto cleanup;
	
	if (strlen(val) == 0) {
		giterr_set(GITERR_INVALID, "Malformed remote '%s' - missing URL", name);
		error = -1;
		goto cleanup;
	}

	remote->repo = repo;
	remote->url = git__strdup(val);
	GITERR_CHECK_ALLOC(remote->url);

	git_buf_clear(&buf);
	if (git_buf_printf(&buf, "remote.%s.pushurl", name) < 0) {
		error = -1;
		goto cleanup;
	}

	error = git_config_get_string(&val, config, git_buf_cstr(&buf));
	if (error == GIT_ENOTFOUND) {
		val = NULL;
		error = 0;
	}

	if (error < 0) {
		error = -1;
		goto cleanup;
	}

	if (val) {
		remote->pushurl = git__strdup(val);
		GITERR_CHECK_ALLOC(remote->pushurl);
	}

	git_buf_clear(&buf);
	if (git_buf_printf(&buf, "remote.%s.fetch", name) < 0) {
		error = -1;
		goto cleanup;
	}

	error = parse_remote_refspec(config, &remote->fetch, git_buf_cstr(&buf), true);
	if (error == GIT_ENOTFOUND)
		error = 0;

	if (error < 0) {
		error = -1;
		goto cleanup;
	}

	git_buf_clear(&buf);
	if (git_buf_printf(&buf, "remote.%s.push", name) < 0) {
		error = -1;
		goto cleanup;
	}

	error = parse_remote_refspec(config, &remote->push, git_buf_cstr(&buf), false);
	if (error == GIT_ENOTFOUND)
		error = 0;

	if (error < 0) {
		error = -1;
		goto cleanup;
	}

	if (download_tags_value(remote, config) < 0)
		goto cleanup;

	*out = remote;

cleanup:
	git_buf_free(&buf);

	if (error < 0)
		git_remote_free(remote);

	return error;
}

static int ensure_remote_name_is_valid(const char *name)
{
	git_buf buf = GIT_BUF_INIT;
	git_refspec refspec;
	int error = -1;

	if (!name || *name == '\0')
		goto cleanup;

	git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", name);
	error = git_refspec__parse(&refspec, git_buf_cstr(&buf), true);

	git_buf_free(&buf);
	git_refspec__free(&refspec);

cleanup:
	if (error)
		giterr_set(
			GITERR_CONFIG,
			"'%s' is not a valid remote name.", name);

	return error;
}

static int update_config_refspec(
	git_config *config,
	const char *remote_name,
	const git_refspec *refspec,
	int git_direction)
{
	git_buf name = GIT_BUF_INIT, value = GIT_BUF_INIT;
	int error = -1;

	if (refspec->src == NULL || refspec->dst == NULL)
		return 0;

	if (git_buf_printf(
		&name,
		"remote.%s.%s",
		remote_name,
		git_direction == GIT_DIR_FETCH ? "fetch" : "push") < 0)
			goto cleanup;

	if (git_refspec__serialize(&value, refspec) < 0)
		goto cleanup;

	error = git_config_set_string(
		config,
		git_buf_cstr(&name),
		git_buf_cstr(&value));

cleanup:
	git_buf_free(&name);
	git_buf_free(&value);

	return error;
}

int git_remote_save(const git_remote *remote)
{
	int error;
	git_config *config;
	const char *tagopt = NULL;
	git_buf buf = GIT_BUF_INIT;

	assert(remote);

	if (ensure_remote_name_is_valid(remote->name) < 0)
		return -1;

	if (git_repository_config__weakptr(&config, remote->repo) < 0)
		return -1;

	if (git_buf_printf(&buf, "remote.%s.url", remote->name) < 0)
		return -1;

	if (git_config_set_string(config, git_buf_cstr(&buf), remote->url) < 0) {
		git_buf_free(&buf);
		return -1;
	}

	git_buf_clear(&buf);
	if (git_buf_printf(&buf, "remote.%s.pushurl", remote->name) < 0)
		return -1;

	if (remote->pushurl) {
		if (git_config_set_string(config, git_buf_cstr(&buf), remote->pushurl) < 0) {
			git_buf_free(&buf);
			return -1;
		}
	} else {
		int error = git_config_delete(config, git_buf_cstr(&buf));
		if (error == GIT_ENOTFOUND) {
			error = 0;
			giterr_clear();
		}
		if (error < 0) {
			git_buf_free(&buf);
			return -1;
		}
	}

	if (update_config_refspec(
		config,
		remote->name,
		&remote->fetch,
		GIT_DIR_FETCH) < 0)
			goto on_error;

	if (update_config_refspec(
		config,
		remote->name,
		&remote->push,
		GIT_DIR_PUSH) < 0)
			goto on_error;

	/*
	 * What action to take depends on the old and new values. This
	 * is describes by the table below. tagopt means whether the
	 * is already a value set in the config
	 *
	 *            AUTO     ALL or NONE
	 *         +-----------------------+
	 *  tagopt | remove  |     set     |
	 *         +---------+-------------|
	 * !tagopt | nothing |     set     |
	 *         +---------+-------------+
	 */

	git_buf_clear(&buf);
	if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
		goto on_error;

	error = git_config_get_string(&tagopt, config, git_buf_cstr(&buf));
	if (error < 0 && error != GIT_ENOTFOUND)
		goto on_error;

	if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
		if (git_config_set_string(config, git_buf_cstr(&buf), "--tags") < 0)
			goto on_error;
	} else if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
		if (git_config_set_string(config, git_buf_cstr(&buf), "--no-tags") < 0)
			goto on_error;
	} else if (tagopt) {
		if (git_config_delete(config, git_buf_cstr(&buf)) < 0)
			goto on_error;
	}

	git_buf_free(&buf);

	return 0;

on_error:
	git_buf_free(&buf);
	return -1;
}

const char *git_remote_name(git_remote *remote)
{
	assert(remote);
	return remote->name;
}

const char *git_remote_url(git_remote *remote)
{
	assert(remote);
	return remote->url;
}

int git_remote_set_url(git_remote *remote, const char* url)
{
	assert(remote);
	assert(url);

	git__free(remote->url);
	remote->url = git__strdup(url);
	GITERR_CHECK_ALLOC(remote->url);

	return 0;
}

const char *git_remote_pushurl(git_remote *remote)
{
	assert(remote);
	return remote->pushurl;
}

int git_remote_set_pushurl(git_remote *remote, const char* url)
{
	assert(remote);

	git__free(remote->pushurl);
	if (url) {
		remote->pushurl = git__strdup(url);
		GITERR_CHECK_ALLOC(remote->pushurl);
	} else {
		remote->pushurl = NULL;
	}
	return 0;
}

int git_remote_set_fetchspec(git_remote *remote, const char *spec)
{
	git_refspec refspec;

	assert(remote && spec);

	if (git_refspec__parse(&refspec, spec, true) < 0)
		return -1;

	git_refspec__free(&remote->fetch);
	remote->fetch.src = refspec.src;
	remote->fetch.dst = refspec.dst;

	return 0;
}

const git_refspec *git_remote_fetchspec(git_remote *remote)
{
	assert(remote);
	return &remote->fetch;
}

int git_remote_set_pushspec(git_remote *remote, const char *spec)
{
	git_refspec refspec;

	assert(remote && spec);

	if (git_refspec__parse(&refspec, spec, false) < 0)
		return -1;

	git_refspec__free(&remote->push);
	remote->push.src = refspec.src;
	remote->push.dst = refspec.dst;

	return 0;
}

const git_refspec *git_remote_pushspec(git_remote *remote)
{
	assert(remote);
	return &remote->push;
}

const char* git_remote__urlfordirection(git_remote *remote, int direction)
{
	assert(remote);

	if (direction == GIT_DIR_FETCH) {
		return remote->url;
	}

	if (direction == GIT_DIR_PUSH) {
		return remote->pushurl ? remote->pushurl : remote->url;
	}

	return NULL;
}

int git_remote_connect(git_remote *remote, int direction)
{
	git_transport *t;
	const char *url;
	int flags = GIT_TRANSPORTFLAGS_NONE;

	assert(remote);

	t = remote->transport;

	url = git_remote__urlfordirection(remote, direction);
	if (url == NULL )
		return -1;

	/* A transport could have been supplied in advance with
	 * git_remote_set_transport */
	if (!t && git_transport_new(&t, url) < 0)
		return -1;

	if (t->set_callbacks &&
		t->set_callbacks(t, remote->callbacks.progress, NULL, remote->callbacks.data) < 0)
		goto on_error;
	
	if (!remote->check_cert)
		flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT;

	if (t->connect(t, url, remote->cred_acquire_cb, direction, flags) < 0)
		goto on_error;

	remote->transport = t;

	return 0;

on_error:
	t->free(t);
	return -1;
}

int git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload)
{
	assert(remote);

	if (!remote->transport) {
		giterr_set(GITERR_NET, "The remote is not connected");
		return -1;
	}

	return remote->transport->ls(remote->transport, list_cb, payload);
}

int git_remote_download(
		git_remote *remote,
		git_transfer_progress_callback progress_cb,
		void *progress_payload)
{
	int error;

	assert(remote);

	if ((error = git_fetch_negotiate(remote)) < 0)
		return error;

	return git_fetch_download_pack(remote, progress_cb, progress_payload);
}

static int update_tips_callback(git_remote_head *head, void *payload)
{
	git_vector *refs = (git_vector *)payload;
	git_vector_insert(refs, head);

        return 0;
}

static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *update_heads, const char *fetchspec_src)
{
	unsigned int i;
	git_remote_head *remote_ref;

	assert(update_heads && fetchspec_src);

	*out = NULL;
    
    git_vector_foreach(update_heads, i, remote_ref) {
        if (strcmp(remote_ref->name, fetchspec_src) == 0) {
            *out = remote_ref;
            break;
		}
	}

	return 0;
}

static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_vector *update_heads, git_reference *ref)
{
	git_reference *resolved_ref = NULL;
	git_reference *tracking_ref = NULL;
	git_buf remote_name = GIT_BUF_INIT;
	int error = 0;

	assert(out && remote && ref);

	*out = NULL;

	if ((error = git_reference_resolve(&resolved_ref, ref)) < 0 ||
		(!git_reference_is_branch(resolved_ref)) ||
		(error = git_branch_tracking(&tracking_ref, resolved_ref)) < 0 ||
		(error = git_refspec_transform_l(&remote_name, &remote->fetch, git_reference_name(tracking_ref))) < 0) {
		/* Not an error if HEAD is orphaned or no tracking branch */
		if (error == GIT_ENOTFOUND)
			error = 0;

		goto cleanup;
	}

	error = remote_head_for_fetchspec_src(out, update_heads, git_buf_cstr(&remote_name));

cleanup:
	git_reference_free(tracking_ref);
	git_reference_free(resolved_ref);
	git_buf_free(&remote_name);
	return error;
}

static int git_remote_write_fetchhead(git_remote *remote, git_vector *update_heads)
{
	struct git_refspec *spec;
	git_reference *head_ref = NULL;
	git_fetchhead_ref *fetchhead_ref;
	git_remote_head *remote_ref, *merge_remote_ref;
	git_vector fetchhead_refs;
	bool include_all_fetchheads;
	unsigned int i = 0;
	int error = 0;

	assert(remote);

	spec = &remote->fetch;

	if (git_vector_init(&fetchhead_refs, update_heads->length, git_fetchhead_ref_cmp) < 0)
		return -1;

	/* Iff refspec is * (but not subdir slash star), include tags */
	include_all_fetchheads = (strcmp(GIT_REFS_HEADS_DIR "*", git_refspec_src(spec)) == 0);

	/* Determine what to merge: if refspec was a wildcard, just use HEAD */
	if (git_refspec_is_wildcard(spec)) {
		if ((error = git_reference_lookup(&head_ref, remote->repo, GIT_HEAD_FILE)) < 0 ||
			(error = remote_head_for_ref(&merge_remote_ref, remote, update_heads, head_ref)) < 0)
				goto cleanup;
	} else {
		/* If we're fetching a single refspec, that's the only thing that should be in FETCH_HEAD. */
		if ((error = remote_head_for_fetchspec_src(&merge_remote_ref, update_heads, git_refspec_src(spec))) < 0)
			goto cleanup;
	}

	/* Create the FETCH_HEAD file */
    git_vector_foreach(update_heads, i, remote_ref) {
		int merge_this_fetchhead = (merge_remote_ref == remote_ref);

		if (!include_all_fetchheads &&
			!git_refspec_src_matches(spec, remote_ref->name) &&
			!merge_this_fetchhead)
			continue;

		if (git_fetchhead_ref_create(&fetchhead_ref,
			&remote_ref->oid,
			merge_this_fetchhead,
			remote_ref->name,
			git_remote_url(remote)) < 0)
			goto cleanup;

		if (git_vector_insert(&fetchhead_refs, fetchhead_ref) < 0)
			goto cleanup;
	}

	git_fetchhead_write(remote->repo, &fetchhead_refs);

cleanup:
	for (i = 0; i < fetchhead_refs.length; ++i)
		git_fetchhead_ref_free(fetchhead_refs.contents[i]);

	git_vector_free(&fetchhead_refs);
	git_reference_free(head_ref);

	return error;
}

int git_remote_update_tips(git_remote *remote)
{
	int error = 0, autotag;
	unsigned int i = 0;
	git_buf refname = GIT_BUF_INIT;
	git_oid old;
	git_odb *odb;
	git_remote_head *head;
	git_reference *ref;
	struct git_refspec *spec;
	git_refspec tagspec;
	git_vector refs, update_heads;

	assert(remote);

	spec = &remote->fetch;
	
	if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
		return -1;

	if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
		return -1;

	/* Make a copy of the transport's refs */
	if (git_vector_init(&refs, 16, NULL) < 0 ||
        git_vector_init(&update_heads, 16, NULL) < 0)
		return -1;

	if (remote->transport->ls(remote->transport, update_tips_callback, &refs) < 0)
		goto on_error;

	/* Let's go find HEAD, if it exists. Check only the first ref in the vector. */
	if (refs.length > 0) {
		head = (git_remote_head *)refs.contents[0];

		if (!strcmp(head->name, GIT_HEAD_FILE))	{
			if (git_reference_create_oid(&ref, remote->repo, GIT_FETCH_HEAD_FILE, &head->oid, 1) < 0)
				goto on_error;

			i = 1;
			git_reference_free(ref);
		}
	}

	for (; i < refs.length; ++i) {
		head = (git_remote_head *)refs.contents[i];
		autotag = 0;

		/* Ignore malformed ref names (which also saves us from tag^{} */
		if (!git_reference_is_valid_name(head->name))
			continue;

		if (git_refspec_src_matches(spec, head->name)) {
			if (git_refspec_transform_r(&refname, spec, head->name) < 0)
				goto on_error;
		} else if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {

			if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_ALL)
				autotag = 1;

			if (!git_refspec_src_matches(&tagspec, head->name))
				continue;

			git_buf_clear(&refname);
			if (git_buf_puts(&refname, head->name) < 0)
				goto on_error;
		} else {
			continue;
		}

		if (autotag && !git_odb_exists(odb, &head->oid))
			continue;

		if (git_vector_insert(&update_heads, head) < 0)
			goto on_error;

		error = git_reference_name_to_oid(&old, remote->repo, refname.ptr);
		if (error < 0 && error != GIT_ENOTFOUND)
			goto on_error;

		if (error == GIT_ENOTFOUND)
			memset(&old, 0, GIT_OID_RAWSZ);

		if (!git_oid_cmp(&old, &head->oid))
			continue;

		/* In autotag mode, don't overwrite any locally-existing tags */
		error = git_reference_create_oid(&ref, remote->repo, refname.ptr, &head->oid, !autotag);
		if (error < 0 && error != GIT_EEXISTS)
			goto on_error;

		git_reference_free(ref);

		if (remote->callbacks.update_tips != NULL) {
			if (remote->callbacks.update_tips(refname.ptr, &old, &head->oid, remote->callbacks.data) < 0)
				goto on_error;
		}
	}

	if (git_remote_update_fetchhead(remote) &&
		(error = git_remote_write_fetchhead(remote, &update_heads)) < 0)
		goto on_error;

	git_vector_free(&refs);
	git_vector_free(&update_heads);
	git_refspec__free(&tagspec);
	git_buf_free(&refname);
	return 0;

on_error:
	git_vector_free(&refs);
	git_vector_free(&update_heads);
	git_refspec__free(&tagspec);
	git_buf_free(&refname);
	return -1;

}

int git_remote_connected(git_remote *remote)
{
	int connected;

	assert(remote);

	if (!remote->transport || !remote->transport->is_connected)
		return 0;

	/* Ask the transport if it's connected. */
	remote->transport->is_connected(remote->transport, &connected);

	return connected;
}

void git_remote_stop(git_remote *remote)
{
	if (remote->transport->cancel)
		remote->transport->cancel(remote->transport);
}

void git_remote_disconnect(git_remote *remote)
{
	assert(remote);

	if (git_remote_connected(remote))
		remote->transport->close(remote->transport);
}

void git_remote_free(git_remote *remote)
{
	if (remote == NULL)
		return;

	if (remote->transport != NULL) {
		git_remote_disconnect(remote);

		remote->transport->free(remote->transport);
		remote->transport = NULL;
	}

	git_vector_free(&remote->refs);

	git_refspec__free(&remote->fetch);
	git_refspec__free(&remote->push);
	git__free(remote->url);
	git__free(remote->pushurl);
	git__free(remote->name);
	git__free(remote);
}

struct cb_data {
	git_vector *list;
	regex_t *preg;
};

static int remote_list_cb(const git_config_entry *entry, void *data_)
{
	struct cb_data *data = (struct cb_data *)data_;
	size_t nmatch = 2;
	regmatch_t pmatch[2];
	const char *name = entry->name;

	if (!regexec(data->preg, name, nmatch, pmatch, 0)) {
		char *remote_name = git__strndup(&name[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
		GITERR_CHECK_ALLOC(remote_name);

		if (git_vector_insert(data->list, remote_name) < 0)
			return -1;
	}

	return 0;
}

int git_remote_list(git_strarray *remotes_list, git_repository *repo)
{
	git_config *cfg;
	git_vector list;
	regex_t preg;
	struct cb_data data;
	int error;

	if (git_repository_config__weakptr(&cfg, repo) < 0)
		return -1;

	if (git_vector_init(&list, 4, NULL) < 0)
		return -1;

	if (regcomp(&preg, "^remote\\.(.*)\\.url$", REG_EXTENDED) < 0) {
		giterr_set(GITERR_OS, "Remote catch regex failed to compile");
		return -1;
	}

	data.list = &list;
	data.preg = &preg;
	error = git_config_foreach(cfg, remote_list_cb, &data);
	regfree(&preg);
	if (error < 0) {
		size_t i;
		char *elem;
		git_vector_foreach(&list, i, elem) {
			git__free(elem);
		}

		git_vector_free(&list);

		/* cb error is converted to GIT_EUSER by git_config_foreach */
		if (error == GIT_EUSER)
			error = -1;

		return error;
	}

	remotes_list->strings = (char **)list.contents;
	remotes_list->count = list.length;

	return 0;
}

int git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url)
{
	git_buf buf = GIT_BUF_INIT;

	if (git_buf_printf(&buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0)
		return -1;

	if (git_remote_new(out, repo, name, url, git_buf_cstr(&buf)) < 0)
		goto on_error;

	git_buf_free(&buf);

	if (git_remote_save(*out) < 0)
		goto on_error;

	return 0;

on_error:
	git_buf_free(&buf);
	git_remote_free(*out);
	return -1;
}

void git_remote_check_cert(git_remote *remote, int check)
{
	assert(remote);

	remote->check_cert = check;
}

void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks)
{
	assert(remote && callbacks);

	memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks));

	if (remote->transport && remote->transport->set_callbacks)
		remote->transport->set_callbacks(remote->transport,
			remote->callbacks.progress,
			NULL,
			remote->callbacks.data);
}

void git_remote_set_cred_acquire_cb(
	git_remote *remote,
	git_cred_acquire_cb cred_acquire_cb)
{
	assert(remote);

	remote->cred_acquire_cb = cred_acquire_cb;
}

int git_remote_set_transport(git_remote *remote, git_transport *transport)
{
	assert(remote && transport);

	if (remote->transport) {
		giterr_set(GITERR_NET, "A transport is already bound to this remote");
		return -1;
	}

	remote->transport = transport;
	return 0;
}

const git_transfer_progress* git_remote_stats(git_remote *remote)
{
	assert(remote);
	return &remote->stats;
}

int git_remote_autotag(git_remote *remote)
{
	return remote->download_tags;
}

void git_remote_set_autotag(git_remote *remote, int value)
{
	remote->download_tags = value;
}

static int ensure_remote_doesnot_exist(git_repository *repo, const char *name)
{
	int error;
	git_remote *remote;

	error = git_remote_load(&remote, repo, name);

	if (error == GIT_ENOTFOUND)
		return 0;

	if (error < 0)
		return error;

	git_remote_free(remote);

	giterr_set(
		GITERR_CONFIG,
		"Remote '%s' already exists.", name);

	return GIT_EEXISTS;
}

static int rename_remote_config_section(
	git_repository *repo,
	const char *old_name,
	const char *new_name)
{
	git_buf old_section_name = GIT_BUF_INIT,
		new_section_name = GIT_BUF_INIT;
	int error = -1;

	if (git_buf_printf(&old_section_name, "remote.%s", old_name) < 0)
		goto cleanup;

	if (git_buf_printf(&new_section_name, "remote.%s", new_name) < 0)
		goto cleanup;

	error = git_config_rename_section(
		repo,
		git_buf_cstr(&old_section_name),
		git_buf_cstr(&new_section_name));

cleanup:
	git_buf_free(&old_section_name);
	git_buf_free(&new_section_name);

	return error;
}

struct update_data
{
	git_config *config;
	const char *old_remote_name;
	const char *new_remote_name;
};

static int update_config_entries_cb(
	const git_config_entry *entry,
	void *payload)
{
	struct update_data *data = (struct update_data *)payload;

	if (strcmp(entry->value, data->old_remote_name))
		return 0;

	return git_config_set_string(
		data->config,
		entry->name,
		data->new_remote_name);
}

static int update_branch_remote_config_entry(
	git_repository *repo,
	const char *old_name,
	const char *new_name)
{
	git_config *config;
	struct update_data data;

	if (git_repository_config__weakptr(&config, repo) < 0)
		return -1;

	data.config = config;
	data.old_remote_name = old_name;
	data.new_remote_name = new_name;

	return git_config_foreach_match(
		config,
		"branch\\..+\\.remote",
		update_config_entries_cb, &data);
}

static int rename_cb(const char *ref, void *data)
{
	if (git__prefixcmp(ref, GIT_REFS_REMOTES_DIR))
		return 0;
	
	return git_vector_insert((git_vector *)data, git__strdup(ref));
}

static int rename_one_remote_reference(
	git_repository *repo,
	const char *reference_name,
	const char *old_remote_name,
	const char *new_remote_name)
{
	int error = -1;
	git_buf new_name = GIT_BUF_INIT;
	git_reference *reference = NULL;

	if (git_buf_printf(
		&new_name,
		GIT_REFS_REMOTES_DIR "%s%s",
		new_remote_name,
		reference_name + strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name)) < 0)
			return -1;

	if (git_reference_lookup(&reference, repo, reference_name) < 0)
		goto cleanup;

	error = git_reference_rename(reference, git_buf_cstr(&new_name), 0);

cleanup:
	git_reference_free(reference);
	git_buf_free(&new_name);
	return error;
}

static int rename_remote_references(
	git_repository *repo,
	const char *old_name,
	const char *new_name)
{
	git_vector refnames;
	int error = -1;
	unsigned int i;
	char *name;

	if (git_vector_init(&refnames, 8, NULL) < 0)
		goto cleanup;

	if (git_reference_foreach(
		repo,
		GIT_REF_LISTALL,
		rename_cb,
		&refnames) < 0)
			goto cleanup;

	git_vector_foreach(&refnames, i, name) {
		if ((error = rename_one_remote_reference(repo, name, old_name, new_name)) < 0)
			goto cleanup;
	}

	error = 0;
cleanup:
	git_vector_foreach(&refnames, i, name) {
		git__free(name);
	}

	git_vector_free(&refnames);
	return error;
}

static int rename_fetch_refspecs(
	git_remote *remote,
	const char *new_name,
	int (*callback)(const char *problematic_refspec, void *payload),
	void *payload)
{
	git_config *config;
	const git_refspec *fetch_refspec;
	git_buf dst_prefix = GIT_BUF_INIT, serialized = GIT_BUF_INIT;
	const char* pos;
	int error = -1;

	fetch_refspec = git_remote_fetchspec(remote);

	/* Is there a refspec to deal with? */
	if (fetch_refspec->src == NULL &&
		fetch_refspec->dst == NULL)
		return 0;

	if (git_refspec__serialize(&serialized, fetch_refspec) < 0)
		goto cleanup;

	/* Is it an in-memory remote? */
	if (remote->name == '\0') {
		error = (callback(git_buf_cstr(&serialized), payload) < 0) ? GIT_EUSER : 0;
		goto cleanup;
	}

	if (git_buf_printf(&dst_prefix, ":refs/remotes/%s/", remote->name) < 0)
		goto cleanup;

	pos = strstr(git_buf_cstr(&serialized), git_buf_cstr(&dst_prefix));

	/* Does the dst part of the refspec follow the extected standard format? */
	if (!pos) {
		error = (callback(git_buf_cstr(&serialized), payload) < 0) ? GIT_EUSER : 0;
		goto cleanup;
	}

	if (git_buf_splice(
		&serialized,
		pos - git_buf_cstr(&serialized) + strlen(":refs/remotes/"),
		strlen(remote->name), new_name,
		strlen(new_name)) < 0)
			goto cleanup;

	git_refspec__free(&remote->fetch);

	if (git_refspec__parse(&remote->fetch, git_buf_cstr(&serialized), true) < 0)
		goto cleanup;

	if (git_repository_config__weakptr(&config, remote->repo) < 0)
		goto cleanup;

	error = update_config_refspec(config, new_name, &remote->fetch, GIT_DIR_FETCH);

cleanup:
	git_buf_free(&serialized);
	git_buf_free(&dst_prefix);
	return error;
}

int git_remote_rename(
	git_remote *remote,
	const char *new_name,
	int (*callback)(const char *problematic_refspec, void *payload),
	void *payload)
{
	int error;

	assert(remote && new_name);

	if ((error = ensure_remote_doesnot_exist(remote->repo, new_name)) < 0)
		return error;

	if ((error = ensure_remote_name_is_valid(new_name)) < 0)
		return error;

	if (!remote->name) {
		if ((error = rename_fetch_refspecs(
			remote,
			new_name,
			callback,
			payload)) < 0)
			return error;

		remote->name = git__strdup(new_name);

		return git_remote_save(remote);
	}

	if ((error = rename_remote_config_section(
		remote->repo,
		remote->name,
		new_name)) < 0)
			return error;

	if ((error = update_branch_remote_config_entry(
		remote->repo,
		remote->name,
		new_name)) < 0)
			return error;

	if ((error = rename_remote_references(
		remote->repo,
		remote->name,
		new_name)) < 0)
			return error;

	if ((error = rename_fetch_refspecs(
		remote,
		new_name,
		callback,
		payload)) < 0)
		return error;

	git__free(remote->name);
	remote->name = git__strdup(new_name);

	return 0;
}

int git_remote_update_fetchhead(git_remote *remote)
{
	return remote->update_fetchhead;
}

void git_remote_set_update_fetchhead(git_remote *remote, int value)
{
	remote->update_fetchhead = value;
}
