#include "clar_libgit2.h"
#include "buffer.h"
#include "posix.h"
#include "index.h"

static git_repository *g_repo = NULL;

void test_index_filemodes__initialize(void)
{
	g_repo = cl_git_sandbox_init("filemodes");
}

void test_index_filemodes__cleanup(void)
{
	cl_git_sandbox_cleanup();
}

void test_index_filemodes__read(void)
{
	git_index *index;
	unsigned int i;
	static bool expected[6] = { 0, 1, 0, 1, 0, 1 };

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_assert_equal_i(6, (int)git_index_entrycount(index));

	for (i = 0; i < 6; ++i) {
		const git_index_entry *entry = git_index_get_byindex(index, i);
		cl_assert(entry != NULL);
		cl_assert(((entry->mode & 0100) ? 1 : 0) == expected[i]);
	}

	git_index_free(index);
}

static void replace_file_with_mode(
	const char *filename, const char *backup, unsigned int create_mode)
{
	git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT;

	cl_git_pass(git_buf_joinpath(&path, "filemodes", filename));
	cl_git_pass(git_buf_printf(&content, "%s as %08u (%d)",
		filename, create_mode, rand()));

	cl_git_pass(p_rename(path.ptr, backup));
	cl_git_write2file(
		path.ptr, content.ptr, content.size,
		O_WRONLY|O_CREAT|O_TRUNC, create_mode);

	git_buf_free(&path);
	git_buf_free(&content);
}

#define add_and_check_mode(I,F,X) add_and_check_mode_(I,F,X,__FILE__,__LINE__)

static void add_and_check_mode_(
	git_index *index, const char *filename, unsigned int expect_mode,
	const char *file, int line)
{
	size_t pos;
	const git_index_entry *entry;

	cl_git_pass(git_index_add_bypath(index, filename));

	clar__assert(!git_index_find(&pos, index, filename),
		file, line, "Cannot find index entry", NULL, 1);

	entry = git_index_get_byindex(index, pos);

	clar__assert_equal(file, line, "Expected mode does not match index",
		1, "%07o", (unsigned int)entry->mode, (unsigned int)expect_mode);
}

void test_index_filemodes__untrusted(void)
{
	git_index *index;

	cl_repo_set_bool(g_repo, "core.filemode", false);

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) != 0);

	/* 1 - add 0644 over existing 0644 -> expect 0644 */
	replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);

	/* 2 - add 0644 over existing 0755 -> expect 0755 */
	replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);

	/* 3 - add 0755 over existing 0644 -> expect 0644 */
	replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);

	/* 4 - add 0755 over existing 0755 -> expect 0755 */
	replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);

	/*  5 - add new 0644 -> expect 0644 */
	cl_git_write2file("filemodes/new_off", "blah", 0,
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
	add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);

	/* 6 - add new 0755 -> expect 0644 if core.filemode == false */
	cl_git_write2file("filemodes/new_on", "blah", 0,
		O_WRONLY | O_CREAT | O_TRUNC, 0755);
	add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB);

	git_index_free(index);
}

void test_index_filemodes__trusted(void)
{
	git_index *index;

	/* Only run these tests on platforms where I can actually
	 * chmod a file and get the stat results I expect!
	 */
	if (!cl_is_chmod_supported())
		return;

	cl_repo_set_bool(g_repo, "core.filemode", true);

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_assert((git_index_caps(index) & GIT_INDEXCAP_NO_FILEMODE) == 0);

	/* 1 - add 0644 over existing 0644 -> expect 0644 */
	replace_file_with_mode("exec_off", "filemodes/exec_off.0", 0644);
	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB);

	/* 2 - add 0644 over existing 0755 -> expect 0644 */
	replace_file_with_mode("exec_on", "filemodes/exec_on.0", 0644);
	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB);

	/* 3 - add 0755 over existing 0644 -> expect 0755 */
	replace_file_with_mode("exec_off", "filemodes/exec_off.1", 0755);
	add_and_check_mode(index, "exec_off", GIT_FILEMODE_BLOB_EXECUTABLE);

	/* 4 - add 0755 over existing 0755 -> expect 0755 */
	replace_file_with_mode("exec_on", "filemodes/exec_on.1", 0755);
	add_and_check_mode(index, "exec_on", GIT_FILEMODE_BLOB_EXECUTABLE);

	/*  5 - add new 0644 -> expect 0644 */
	cl_git_write2file("filemodes/new_off", "blah", 0,
		O_WRONLY | O_CREAT | O_TRUNC, 0644);
	add_and_check_mode(index, "new_off", GIT_FILEMODE_BLOB);

	/* 6 - add 0755 -> expect 0755 */
	cl_git_write2file("filemodes/new_on", "blah", 0,
		O_WRONLY | O_CREAT | O_TRUNC, 0755);
	add_and_check_mode(index, "new_on", GIT_FILEMODE_BLOB_EXECUTABLE);

	git_index_free(index);
}

#define add_entry_and_check_mode(I,FF,X) add_entry_and_check_mode_(I,FF,X,__FILE__,__LINE__)

static void add_entry_and_check_mode_(
	git_index *index, bool from_file, git_filemode_t mode,
	const char *file, int line)
{
	size_t pos;
	const git_index_entry* entry;
	git_index_entry new_entry;

	/* If old_filename exists, we copy that to the new file, and test
	 * git_index_add(), otherwise create a new entry testing git_index_add_frombuffer
	 */
	if (from_file)
	{
		clar__assert(!git_index_find(&pos, index, "exec_off"),
			file, line, "Cannot find original index entry", NULL, 1);

		entry = git_index_get_byindex(index, pos);

		memcpy(&new_entry, entry, sizeof(new_entry));
	}
	else
		memset(&new_entry, 0x0, sizeof(git_index_entry));

	new_entry.path = "filemodes/explicit_test";
	new_entry.mode = mode;

	if (from_file)
	{
		clar__assert(!git_index_add(index, &new_entry),
			file, line, "Cannot add index entry", NULL, 1);
	}
	else
	{
		const char *content = "hey there\n";
		clar__assert(!git_index_add_frombuffer(index, &new_entry, content, strlen(content)),
			file, line, "Cannot add index entry from buffer", NULL, 1);
	}

	clar__assert(!git_index_find(&pos, index, "filemodes/explicit_test"),
		file, line, "Cannot find new index entry", NULL, 1);

	entry = git_index_get_byindex(index, pos);

	clar__assert_equal(file, line, "Expected mode does not match index",
		1, "%07o", (unsigned int)entry->mode, (unsigned int)mode);
}

void test_index_filemodes__explicit(void)
{
	git_index *index;

	/* These tests should run and work everywhere, as the filemode is
	 * given explicitly to git_index_add or git_index_add_frombuffer
	 */
	cl_repo_set_bool(g_repo, "core.filemode", false);

	cl_git_pass(git_repository_index(&index, g_repo));

	/* Each of these tests keeps overwriting the same file in the index. */
	/* 1 - add new 0644 entry  */
	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB);

	/* 2 - add 0755 entry over existing 0644 */
	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB_EXECUTABLE);

	/* 3 - add 0644 entry over existing 0755 */
	add_entry_and_check_mode(index, true, GIT_FILEMODE_BLOB);

	/* 4 - add 0755 buffer entry over existing 0644  */
	add_entry_and_check_mode(index, false, GIT_FILEMODE_BLOB_EXECUTABLE);

	/* 5 - add 0644 buffer entry over existing 0755 */
	add_entry_and_check_mode(index, false, GIT_FILEMODE_BLOB);

	git_index_free(index);
}

void test_index_filemodes__invalid(void)
{
	git_index *index;
	git_index_entry entry;
	const git_index_entry *dummy;

	cl_git_pass(git_repository_index(&index, g_repo));

	/* add a dummy file so that we have a valid id */
	cl_git_mkfile("./filemodes/dummy-file.txt", "new-file\n");
	cl_git_pass(git_index_add_bypath(index, "dummy-file.txt"));
	cl_assert((dummy = git_index_get_bypath(index, "dummy-file.txt", 0)));

	GIT_IDXENTRY_STAGE_SET(&entry, 0);
	entry.path = "foo";
	entry.mode = GIT_OBJ_BLOB;
	git_oid_cpy(&entry.id, &dummy->id);
	cl_git_fail(git_index_add(index, &entry));

	entry.mode = GIT_FILEMODE_BLOB;
	cl_git_pass(git_index_add(index, &entry));

	git_index_free(index);
}
