#include "clar_libgit2.h"
#include "thread_helpers.h"

#ifdef GIT_THREADS

# if defined(GIT_WIN32)
#  define git_thread_yield() Sleep(0)
# elif defined(__FreeBSD__) || defined(__MidnightBSD__) || defined(__DragonFly__)
#  define git_thread_yield() pthread_yield()
# else
#  define git_thread_yield() sched_yield()
# endif

#else
# define git_thread_yield() (void)0
#endif

static git_repository *_repo;
static git_tree *_a, *_b;
static git_atomic _counts[4];
static int _check_counts;
#ifdef GIT_WIN32
static int _retries;
#endif

#define THREADS 20

void test_threads_diff__initialize(void)
{
#ifdef GIT_WIN32
	_retries = git_win32__retries;
	git_win32__retries = 1;
#endif
}

void test_threads_diff__cleanup(void)
{
	cl_git_sandbox_cleanup();

#ifdef GIT_WIN32
	git_win32__retries = _retries;
#endif
}

static void setup_trees(void)
{
	git_index *idx;

	_repo = cl_git_sandbox_reopen(); /* reopen sandbox to flush caches */

	/* avoid competing to load initial index */
	cl_git_pass(git_repository_index(&idx, _repo));
	git_index_free(idx);

	cl_git_pass(git_revparse_single(
		(git_object **)&_a, _repo, "0017bd4ab1^{tree}"));
	cl_git_pass(git_revparse_single(
		(git_object **)&_b, _repo, "26a125ee1b^{tree}"));

	memset(_counts, 0, sizeof(_counts));
}

static void free_trees(void)
{
	git_tree_free(_a); _a = NULL;
	git_tree_free(_b); _b = NULL;

	if (_check_counts) {
		cl_assert_equal_i(288, git_atomic_get(&_counts[0]));
		cl_assert_equal_i(112, git_atomic_get(&_counts[1]));
		cl_assert_equal_i( 80, git_atomic_get(&_counts[2]));
		cl_assert_equal_i( 96, git_atomic_get(&_counts[3]));
	}
}

static void *run_index_diffs(void *arg)
{
	int thread = *(int *)arg;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff *diff = NULL;
	size_t i;
	int exp[4] = { 0, 0, 0, 0 };

	switch (thread & 0x03) {
	case 0: /* diff index to workdir */;
		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, NULL, &opts));
		break;
	case 1: /* diff tree 'a' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, NULL, &opts));
		break;
	case 2: /* diff tree 'b' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, NULL, &opts));
		break;
	case 3: /* diff index to workdir (explicit index) */;
		{
			git_index *idx;
			cl_git_pass(git_repository_index(&idx, _repo));
			cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
			git_index_free(idx);
			break;
		}
	}

	/* keep some diff stats to make sure results are as expected */

	i = git_diff_num_deltas(diff);
	git_atomic_add(&_counts[0], (int32_t)i);
	exp[0] = (int)i;

	while (i > 0) {
		switch (git_diff_get_delta(diff, --i)->status) {
		case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break;
		case GIT_DELTA_ADDED:    exp[2]++; git_atomic_inc(&_counts[2]); break;
		case GIT_DELTA_DELETED:  exp[3]++; git_atomic_inc(&_counts[3]); break;
		default: break;
		}
	}

	switch (thread & 0x03) {
	case 0: case 3:
		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(4, exp[1]);
		cl_assert_equal_i(0, exp[2]); cl_assert_equal_i(4, exp[3]);
		break;
	case 1:
		cl_assert_equal_i(12, exp[0]); cl_assert_equal_i(3, exp[1]);
		cl_assert_equal_i(7, exp[2]); cl_assert_equal_i(2, exp[3]);
		break;
	case 2:
		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(3, exp[1]);
		cl_assert_equal_i(3, exp[2]); cl_assert_equal_i(2, exp[3]);
		break;
	}

	git_diff_free(diff);
	giterr_clear();

	return arg;
}

void test_threads_diff__concurrent_diffs(void)
{
	_repo = cl_git_sandbox_init("status");
	_check_counts = 1;

	run_in_parallel(
		5, 32, run_index_diffs, setup_trees, free_trees);
}

static void *run_index_diffs_with_modifier(void *arg)
{
	int thread = *(int *)arg;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff *diff = NULL;
	git_index *idx = NULL;

	cl_git_pass(git_repository_index(&idx, _repo));

	/* have first thread altering the index as we go */
	if (thread == 0) {
		int i;

		for (i = 0; i < 300; ++i) {
			switch (i & 0x03) {
			case 0: (void)git_index_add_bypath(idx, "new_file"); break;
			case 1: (void)git_index_remove_bypath(idx, "modified_file"); break;
			case 2: (void)git_index_remove_bypath(idx, "new_file"); break;
			case 3: (void)git_index_add_bypath(idx, "modified_file"); break;
			}
			git_thread_yield();
		}

		goto done;
	}

	/* only use explicit index in this test to prevent reloading */

	switch (thread & 0x03) {
	case 0: /* diff index to workdir */;
		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
		break;
	case 1: /* diff tree 'a' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _a, idx, &opts));
		break;
	case 2: /* diff tree 'b' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, _repo, _b, idx, &opts));
		break;
	case 3: /* diff index to workdir reversed */;
		opts.flags |= GIT_DIFF_REVERSE;
		cl_git_pass(git_diff_index_to_workdir(&diff, _repo, idx, &opts));
		break;
	}

	/* results will be unpredictable with index modifier thread running */

	git_diff_free(diff);

done:
	git_index_free(idx);
	giterr_clear();

	return arg;
}

void test_threads_diff__with_concurrent_index_modified(void)
{
	_repo = cl_git_sandbox_init("status");
	_check_counts = 0;

	run_in_parallel(
		5, 16, run_index_diffs_with_modifier, setup_trees, free_trees);
}
