#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;

#define THREADS 20

void test_threads_diff__cleanup(void)
{
	cl_git_sandbox_cleanup();
}

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);
}
