#include "clar_libgit2.h"
#include "git2/refdb.h"
#include "refdb.h"

static git_repository *g_repo;
static int g_expected = 0;

void test_threads_refdb__initialize(void)
{
	g_repo = NULL;
}

void test_threads_refdb__cleanup(void)
{
	cl_git_sandbox_cleanup();
	g_repo = NULL;
}

#define REPEAT 20
#define THREADS 20
/* Number of references to create or delete in each thread */
#define NREFS 10

struct th_data {
	cl_git_thread_err error;
	int id;
	const char *path;
};

static void *iterate_refs(void *arg)
{
	struct th_data *data = (struct th_data *) arg;
	git_reference_iterator *i;
	git_reference *ref;
	int count = 0, error;
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));
	do {
		error = git_reference_iterator_new(&i, repo);
	} while (error == GIT_ELOCKED);
	cl_git_thread_pass(data, error);

	for (count = 0; !git_reference_next(&ref, i); ++count) {
		cl_assert(ref != NULL);
		git_reference_free(ref);
	}

	if (g_expected > 0)
		cl_assert_equal_i(g_expected, count);

	git_reference_iterator_free(i);

	git_repository_free(repo);
	giterr_clear();
	return arg;
}

static void *create_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_oid head;
	char name[128];
	git_reference *ref[NREFS];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	do {
		error = git_reference_name_to_id(&head, repo, "HEAD");
	} while (error == GIT_ELOCKED);
	cl_git_thread_pass(data, error);

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i);
		do {
			error = git_reference_create(&ref[i], repo, name, &head, 0, NULL);
		} while (error == GIT_ELOCKED);
		cl_git_thread_pass(data, error);

		if (i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	for (i = 0; i < NREFS; ++i)
		git_reference_free(ref[i]);

	git_repository_free(repo);

	giterr_clear();
	return arg;
}

static void *delete_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_reference *ref;
	char name[128];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(
			name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i);

		if (!git_reference_lookup(&ref, repo, name)) {
			do {
				error = git_reference_delete(ref);
			} while (error == GIT_ELOCKED);
			/* Sometimes we race with other deleter threads */
			if (error == GIT_ENOTFOUND)
				error = 0;

			cl_git_thread_pass(data, error);
			git_reference_free(ref);
		}

		if (i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	git_repository_free(repo);
	giterr_clear();
	return arg;
}

void test_threads_refdb__edit_while_iterate(void)
{
	int r, t;
	struct th_data th_data[THREADS];
	git_oid head;
	git_reference *ref;
	char name[128];
	git_refdb *refdb;

#ifdef GIT_THREADS
	git_thread th[THREADS];
#endif

	g_repo = cl_git_sandbox_init("testrepo2");

	cl_git_pass(git_reference_name_to_id(&head, g_repo, "HEAD"));

	/* make a bunch of references */

	for (r = 0; r < 50; ++r) {
		p_snprintf(name, sizeof(name), "refs/heads/starter-%03d", r);
		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
		git_reference_free(ref);
	}

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);

	g_expected = -1;

	g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */

	for (t = 0; t < THREADS; ++t) {
		void *(*fn)(void *arg);

		switch (t & 0x3) {
		case 0:  fn = create_refs;  break;
		case 1:  fn = delete_refs;  break;
		default: fn = iterate_refs; break;
		}

		th_data[t].id = t;
		th_data[t].path = git_repository_path(g_repo);

#ifdef GIT_THREADS
		cl_git_pass(git_thread_create(&th[t], fn, &th_data[t]));
#else
		fn(&th_data[t]);
#endif
	}

#ifdef GIT_THREADS
	for (t = 0; t < THREADS; ++t) {
		cl_git_pass(git_thread_join(&th[t], NULL));
		cl_git_thread_check(&th_data[t]);
	}

	memset(th, 0, sizeof(th));

	for (t = 0; t < THREADS; ++t) {
		th_data[t].id = t;
		cl_git_pass(git_thread_create(&th[t], iterate_refs, &th_data[t]));
	}

	for (t = 0; t < THREADS; ++t) {
		cl_git_pass(git_thread_join(&th[t], NULL));
		cl_git_thread_check(&th_data[t]);
	}
#endif
}
