#include "test-tool.h"
#include "environment.h"
#include "name-hash.h"
#include "parse-options.h"
#include "read-cache-ll.h"
#include "repository.h"
#include "setup.h"
#include "trace.h"

static int single;
static int multi;
static int count = 1;
static int dump;
static int perf;
static int analyze;
static int analyze_step;

/*
 * Dump the contents of the "dir" and "name" hash tables to stdout.
 * If you sort the result, you can compare it with the other type
 * mode and verify that both single and multi produce the same set.
 */
static void dump_run(void)
{
	struct hashmap_iter iter_dir;
	struct hashmap_iter iter_cache;

	/* Stolen from name-hash.c */
	struct dir_entry {
		struct hashmap_entry ent;
		struct dir_entry *parent;
		int nr;
		unsigned int namelen;
		char name[FLEX_ARRAY];
	};

	struct dir_entry *dir;
	struct cache_entry *ce;

	repo_read_index(the_repository);
	if (single) {
		test_lazy_init_name_hash(the_repository->index, 0);
	} else {
		int nr_threads_used = test_lazy_init_name_hash(the_repository->index, 1);
		if (!nr_threads_used)
			die("non-threaded code path used");
	}

	hashmap_for_each_entry(&the_repository->index->dir_hash, &iter_dir, dir,
				ent /* member name */)
		printf("dir %08x %7d %s\n", dir->ent.hash, dir->nr, dir->name);

	hashmap_for_each_entry(&the_repository->index->name_hash, &iter_cache, ce,
				ent /* member name */)
		printf("name %08x %s\n", ce->ent.hash, ce->name);

	discard_index(the_repository->index);
}

/*
 * Run the single or multi threaded version "count" times and
 * report on the time taken.
 */
static uint64_t time_runs(int try_threaded)
{
	uint64_t t0, t1, t2;
	uint64_t sum = 0;
	uint64_t avg;
	int nr_threads_used;
	int i;

	for (i = 0; i < count; i++) {
		t0 = getnanotime();
		repo_read_index(the_repository);
		t1 = getnanotime();
		nr_threads_used = test_lazy_init_name_hash(the_repository->index, try_threaded);
		t2 = getnanotime();

		sum += (t2 - t1);

		if (try_threaded && !nr_threads_used)
			die("non-threaded code path used");

		if (nr_threads_used)
			printf("%f %f %d multi %d\n",
				   ((double)(t1 - t0))/1000000000,
				   ((double)(t2 - t1))/1000000000,
				   the_repository->index->cache_nr,
				   nr_threads_used);
		else
			printf("%f %f %d single\n",
				   ((double)(t1 - t0))/1000000000,
				   ((double)(t2 - t1))/1000000000,
				   the_repository->index->cache_nr);
		fflush(stdout);

		discard_index(the_repository->index);
	}

	avg = sum / count;
	if (count > 1)
		printf("avg %f %s\n",
			   (double)avg/1000000000,
			   (try_threaded) ? "multi" : "single");

	return avg;
}

/*
 * Try a series of runs varying the "istate->cache_nr" and
 * try to find a good value for the multi-threaded criteria.
 */
static void analyze_run(void)
{
	uint64_t t1s, t1m, t2s, t2m;
	int cache_nr_limit;
	int nr_threads_used = 0;
	int i;
	int nr;

	repo_read_index(the_repository);
	cache_nr_limit = the_repository->index->cache_nr;
	discard_index(the_repository->index);

	nr = analyze;
	while (1) {
		uint64_t sum_single = 0;
		uint64_t sum_multi = 0;
		uint64_t avg_single;
		uint64_t avg_multi;

		if (nr > cache_nr_limit)
			nr = cache_nr_limit;

		for (i = 0; i < count; i++) {
			repo_read_index(the_repository);
			the_repository->index->cache_nr = nr; /* cheap truncate of index */
			t1s = getnanotime();
			test_lazy_init_name_hash(the_repository->index, 0);
			t2s = getnanotime();
			sum_single += (t2s - t1s);
			the_repository->index->cache_nr = cache_nr_limit;
			discard_index(the_repository->index);

			repo_read_index(the_repository);
			the_repository->index->cache_nr = nr; /* cheap truncate of index */
			t1m = getnanotime();
			nr_threads_used = test_lazy_init_name_hash(the_repository->index, 1);
			t2m = getnanotime();
			sum_multi += (t2m - t1m);
			the_repository->index->cache_nr = cache_nr_limit;
			discard_index(the_repository->index);

			if (!nr_threads_used)
				printf("    [size %8d] [single %f]   non-threaded code path used\n",
					   nr, ((double)(t2s - t1s))/1000000000);
			else
				printf("    [size %8d] [single %f] %c [multi %f %d]\n",
					   nr,
					   ((double)(t2s - t1s))/1000000000,
					   (((t2s - t1s) < (t2m - t1m)) ? '<' : '>'),
					   ((double)(t2m - t1m))/1000000000,
					   nr_threads_used);
			fflush(stdout);
		}
		if (count > 1) {
			avg_single = sum_single / count;
			avg_multi = sum_multi / count;
			if (!nr_threads_used)
				printf("avg [size %8d] [single %f]\n",
					   nr,
					   (double)avg_single/1000000000);
			else
				printf("avg [size %8d] [single %f] %c [multi %f %d]\n",
					   nr,
					   (double)avg_single/1000000000,
					   (avg_single < avg_multi ? '<' : '>'),
					   (double)avg_multi/1000000000,
					   nr_threads_used);
			fflush(stdout);
		}

		if (nr >= cache_nr_limit)
			return;
		nr += analyze_step;
	}
}

int cmd__lazy_init_name_hash(int argc, const char **argv)
{
	const char *usage[] = {
		"test-tool lazy-init-name-hash -d (-s | -m)",
		"test-tool lazy-init-name-hash -p [-c c]",
		"test-tool lazy-init-name-hash -a a [--step s] [-c c]",
		"test-tool lazy-init-name-hash (-s | -m) [-c c]",
		"test-tool lazy-init-name-hash -s -m [-c c]",
		NULL
	};
	struct option options[] = {
		OPT_BOOL('s', "single", &single, "run single-threaded code"),
		OPT_BOOL('m', "multi", &multi, "run multi-threaded code"),
		OPT_INTEGER('c', "count", &count, "number of passes"),
		OPT_BOOL('d', "dump", &dump, "dump hash tables"),
		OPT_BOOL('p', "perf", &perf, "compare single vs multi"),
		OPT_INTEGER('a', "analyze", &analyze, "analyze different multi sizes"),
		OPT_INTEGER(0, "step", &analyze_step, "analyze step factor"),
		OPT_END(),
	};
	const char *prefix;
	uint64_t avg_single, avg_multi;

	prefix = setup_git_directory();

	argc = parse_options(argc, argv, prefix, options, usage, 0);

	/*
	 * istate->dir_hash is only created when ignore_case is set.
	 */
	ignore_case = 1;

	if (dump) {
		if (perf || analyze > 0)
			die("cannot combine dump, perf, or analyze");
		if (count > 1)
			die("count not valid with dump");
		if (single && multi)
			die("cannot use both single and multi with dump");
		if (!single && !multi)
			die("dump requires either single or multi");
		dump_run();
		return 0;
	}

	if (perf) {
		if (analyze > 0)
			die("cannot combine dump, perf, or analyze");
		if (single || multi)
			die("cannot use single or multi with perf");
		avg_single = time_runs(0);
		avg_multi = time_runs(1);
		if (avg_multi > avg_single)
			die("multi is slower");
		return 0;
	}

	if (analyze) {
		if (analyze < 500)
			die("analyze must be at least 500");
		if (!analyze_step)
			analyze_step = analyze;
		if (single || multi)
			die("cannot use single or multi with analyze");
		analyze_run();
		return 0;
	}

	if (!single && !multi)
		die("require either -s or -m or both");

	if (single)
		time_runs(0);
	if (multi)
		time_runs(1);

	return 0;
}
