/*
 * 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 "common.h"
#include "commit.h"
#include "tag.h"
#include "git2/reset.h"
#include "git2/checkout.h"

#define ERROR_MSG "Cannot perform reset"

static int reset_error_invalid(const char *msg)
{
	giterr_set(GITERR_INVALID, "%s - %s", ERROR_MSG, msg);
	return -1;
}

int git_reset(
	git_repository *repo,
	git_object *target,
	git_reset_type reset_type)
{
	git_object *commit = NULL;
	git_index *index = NULL;
	git_tree *tree = NULL;
	int error = -1;
	git_checkout_opts opts;
	git_reference *head = NULL;

	assert(repo && target);
	assert(reset_type == GIT_RESET_SOFT
		|| reset_type == GIT_RESET_MIXED
		|| reset_type == GIT_RESET_HARD);

	if (git_object_owner(target) != repo)
		return reset_error_invalid("The given target does not belong to this repository.");

	if (reset_type != GIT_RESET_SOFT
		&& git_repository__ensure_not_bare(
			repo,
			reset_type == GIT_RESET_MIXED ? "reset mixed" : "reset hard") < 0)
				return GIT_EBAREREPO;

	if (git_object_peel(&commit, target, GIT_OBJ_COMMIT) < 0) {
		reset_error_invalid("The given target does not resolve to a commit");
		goto cleanup;
	}

	//TODO: Check for unmerged entries

	if (git_repository_head(&head, repo) < 0)
		goto cleanup;

	if (git_reference_set_oid(head, git_object_id(commit)) < 0)
		goto cleanup;

	if (reset_type == GIT_RESET_SOFT) {
		error = 0;
		goto cleanup;
	}

	if (git_commit_tree(&tree, (git_commit *)commit) < 0) {
		giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the commit tree.", ERROR_MSG);
		goto cleanup;
	}

	if (git_repository_index(&index, repo) < 0) {
		giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the index.", ERROR_MSG);
		goto cleanup;
	}

	if (git_index_read_tree(index, tree, NULL) < 0) {
		giterr_set(GITERR_INDEX, "%s - Failed to update the index.", ERROR_MSG);
		goto cleanup;
	}

	if (git_index_write(index) < 0) {
		giterr_set(GITERR_INDEX, "%s - Failed to write the index.", ERROR_MSG);
		goto cleanup;
	}

	if (reset_type == GIT_RESET_MIXED) {
		error = 0;
		goto cleanup;
	}

	memset(&opts, 0, sizeof(opts));
	opts.checkout_strategy =
		GIT_CHECKOUT_CREATE_MISSING
		| GIT_CHECKOUT_OVERWRITE_MODIFIED
		| GIT_CHECKOUT_REMOVE_UNTRACKED;

	if (git_checkout_index(repo, &opts, NULL) < 0) {
		giterr_set(GITERR_INDEX, "%s - Failed to checkout the index.", ERROR_MSG);
		goto cleanup;
	}

	error = 0;

cleanup:
	git_reference_free(head);
	git_object_free(commit);
	git_index_free(index);
	git_tree_free(tree);

	return error;
}
