#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "bloom.h"
#include "diff.h"
#include "diffcore.h"
#include "hashmap.h"
#include "commit-graph.h"
#include "commit.h"
#include "commit-slab.h"
#include "tree.h"
#include "tree-walk.h"
#include "config.h"
#include "repository.h"

define_commit_slab(bloom_filter_slab, struct bloom_filter);

static struct bloom_filter_slab bloom_filters;

struct pathmap_hash_entry {
    struct hashmap_entry entry;
    const char path[FLEX_ARRAY];
};

static uint32_t rotate_left(uint32_t value, int32_t count)
{
	uint32_t mask = 8 * sizeof(uint32_t) - 1;
	count &= mask;
	return ((value << count) | (value >> ((-count) & mask)));
}

static inline unsigned char get_bitmask(uint32_t pos)
{
	return ((unsigned char)1) << (pos & (BITS_PER_WORD - 1));
}

static int check_bloom_offset(struct commit_graph *g, uint32_t pos,
			      uint32_t offset)
{
	/*
	 * Note that we allow offsets equal to the data size, which would set
	 * our pointers at one past the end of the chunk memory. This is
	 * necessary because the on-disk index points to the end of the
	 * entries (so we can compute size by comparing adjacent ones). And
	 * naturally the final entry's end is one-past-the-end of the chunk.
	 */
	if (offset <= g->chunk_bloom_data_size - BLOOMDATA_CHUNK_HEADER_SIZE)
		return 0;

	warning("ignoring out-of-range offset (%"PRIuMAX") for changed-path"
		" filter at pos %"PRIuMAX" of %s (chunk size: %"PRIuMAX")",
		(uintmax_t)offset, (uintmax_t)pos,
		g->filename, (uintmax_t)g->chunk_bloom_data_size);
	return -1;
}

int load_bloom_filter_from_graph(struct commit_graph *g,
				 struct bloom_filter *filter,
				 uint32_t graph_pos)
{
	uint32_t lex_pos, start_index, end_index;

	while (graph_pos < g->num_commits_in_base)
		g = g->base_graph;

	/* The commit graph commit 'c' lives in doesn't carry Bloom filters. */
	if (!g->chunk_bloom_indexes)
		return 0;

	lex_pos = graph_pos - g->num_commits_in_base;

	end_index = get_be32(g->chunk_bloom_indexes + 4 * lex_pos);

	if (lex_pos > 0)
		start_index = get_be32(g->chunk_bloom_indexes + 4 * (lex_pos - 1));
	else
		start_index = 0;

	if (check_bloom_offset(g, lex_pos, end_index) < 0 ||
	    check_bloom_offset(g, lex_pos - 1, start_index) < 0)
		return 0;

	if (end_index < start_index) {
		warning("ignoring decreasing changed-path index offsets"
			" (%"PRIuMAX" > %"PRIuMAX") for positions"
			" %"PRIuMAX" and %"PRIuMAX" of %s",
			(uintmax_t)start_index, (uintmax_t)end_index,
			(uintmax_t)(lex_pos-1), (uintmax_t)lex_pos,
			g->filename);
		return 0;
	}

	filter->len = end_index - start_index;
	filter->data = (unsigned char *)(g->chunk_bloom_data +
					sizeof(unsigned char) * start_index +
					BLOOMDATA_CHUNK_HEADER_SIZE);
	filter->version = g->bloom_filter_settings->hash_version;
	filter->to_free = NULL;

	return 1;
}

/*
 * Calculate the murmur3 32-bit hash value for the given data
 * using the given seed.
 * Produces a uniformly distributed hash value.
 * Not considered to be cryptographically secure.
 * Implemented as described in https://en.wikipedia.org/wiki/MurmurHash#Algorithm
 */
static uint32_t murmur3_seeded_v2(uint32_t seed, const char *data, size_t len)
{
	const uint32_t c1 = 0xcc9e2d51;
	const uint32_t c2 = 0x1b873593;
	const uint32_t r1 = 15;
	const uint32_t r2 = 13;
	const uint32_t m = 5;
	const uint32_t n = 0xe6546b64;
	int i;
	uint32_t k1 = 0;
	const char *tail;

	int len4 = len / sizeof(uint32_t);

	uint32_t k;
	for (i = 0; i < len4; i++) {
		uint32_t byte1 = (uint32_t)(unsigned char)data[4*i];
		uint32_t byte2 = ((uint32_t)(unsigned char)data[4*i + 1]) << 8;
		uint32_t byte3 = ((uint32_t)(unsigned char)data[4*i + 2]) << 16;
		uint32_t byte4 = ((uint32_t)(unsigned char)data[4*i + 3]) << 24;
		k = byte1 | byte2 | byte3 | byte4;
		k *= c1;
		k = rotate_left(k, r1);
		k *= c2;

		seed ^= k;
		seed = rotate_left(seed, r2) * m + n;
	}

	tail = (data + len4 * sizeof(uint32_t));

	switch (len & (sizeof(uint32_t) - 1)) {
	case 3:
		k1 ^= ((uint32_t)(unsigned char)tail[2]) << 16;
		/*-fallthrough*/
	case 2:
		k1 ^= ((uint32_t)(unsigned char)tail[1]) << 8;
		/*-fallthrough*/
	case 1:
		k1 ^= ((uint32_t)(unsigned char)tail[0]) << 0;
		k1 *= c1;
		k1 = rotate_left(k1, r1);
		k1 *= c2;
		seed ^= k1;
		break;
	}

	seed ^= (uint32_t)len;
	seed ^= (seed >> 16);
	seed *= 0x85ebca6b;
	seed ^= (seed >> 13);
	seed *= 0xc2b2ae35;
	seed ^= (seed >> 16);

	return seed;
}

static uint32_t murmur3_seeded_v1(uint32_t seed, const char *data, size_t len)
{
	const uint32_t c1 = 0xcc9e2d51;
	const uint32_t c2 = 0x1b873593;
	const uint32_t r1 = 15;
	const uint32_t r2 = 13;
	const uint32_t m = 5;
	const uint32_t n = 0xe6546b64;
	int i;
	uint32_t k1 = 0;
	const char *tail;

	int len4 = len / sizeof(uint32_t);

	uint32_t k;
	for (i = 0; i < len4; i++) {
		uint32_t byte1 = (uint32_t)data[4*i];
		uint32_t byte2 = ((uint32_t)data[4*i + 1]) << 8;
		uint32_t byte3 = ((uint32_t)data[4*i + 2]) << 16;
		uint32_t byte4 = ((uint32_t)data[4*i + 3]) << 24;
		k = byte1 | byte2 | byte3 | byte4;
		k *= c1;
		k = rotate_left(k, r1);
		k *= c2;

		seed ^= k;
		seed = rotate_left(seed, r2) * m + n;
	}

	tail = (data + len4 * sizeof(uint32_t));

	switch (len & (sizeof(uint32_t) - 1)) {
	case 3:
		k1 ^= ((uint32_t)tail[2]) << 16;
		/*-fallthrough*/
	case 2:
		k1 ^= ((uint32_t)tail[1]) << 8;
		/*-fallthrough*/
	case 1:
		k1 ^= ((uint32_t)tail[0]) << 0;
		k1 *= c1;
		k1 = rotate_left(k1, r1);
		k1 *= c2;
		seed ^= k1;
		break;
	}

	seed ^= (uint32_t)len;
	seed ^= (seed >> 16);
	seed *= 0x85ebca6b;
	seed ^= (seed >> 13);
	seed *= 0xc2b2ae35;
	seed ^= (seed >> 16);

	return seed;
}

void bloom_key_fill(struct bloom_key *key, const char *data, size_t len,
		    const struct bloom_filter_settings *settings)
{
	int i;
	const uint32_t seed0 = 0x293ae76f;
	const uint32_t seed1 = 0x7e646e2c;
	uint32_t hash0, hash1;
	if (settings->hash_version == 2) {
		hash0 = murmur3_seeded_v2(seed0, data, len);
		hash1 = murmur3_seeded_v2(seed1, data, len);
	} else {
		hash0 = murmur3_seeded_v1(seed0, data, len);
		hash1 = murmur3_seeded_v1(seed1, data, len);
	}

	key->hashes = (uint32_t *)xcalloc(settings->num_hashes, sizeof(uint32_t));
	for (i = 0; i < settings->num_hashes; i++)
		key->hashes[i] = hash0 + i * hash1;
}

void bloom_key_clear(struct bloom_key *key)
{
	FREE_AND_NULL(key->hashes);
}

void add_key_to_filter(const struct bloom_key *key,
		       struct bloom_filter *filter,
		       const struct bloom_filter_settings *settings)
{
	int i;
	uint64_t mod = filter->len * BITS_PER_WORD;

	for (i = 0; i < settings->num_hashes; i++) {
		uint64_t hash_mod = key->hashes[i] % mod;
		uint64_t block_pos = hash_mod / BITS_PER_WORD;

		filter->data[block_pos] |= get_bitmask(hash_mod);
	}
}

void init_bloom_filters(void)
{
	init_bloom_filter_slab(&bloom_filters);
}

static void free_one_bloom_filter(struct bloom_filter *filter)
{
	if (!filter)
		return;
	free(filter->to_free);
}

void deinit_bloom_filters(void)
{
	deep_clear_bloom_filter_slab(&bloom_filters, free_one_bloom_filter);
}

struct bloom_keyvec *bloom_keyvec_new(const char *path, size_t len,
				      const struct bloom_filter_settings *settings)
{
	struct bloom_keyvec *vec;
	const char *p;
	size_t sz;
	size_t nr = 1;

	p = path;
	while (*p) {
		/*
		 * At this point, the path is normalized to use Unix-style
		 * path separators. This is required due to how the
		 * changed-path Bloom filters store the paths.
		 */
		if (*p == '/')
			nr++;
		p++;
	}

	sz = sizeof(struct bloom_keyvec);
	sz += nr * sizeof(struct bloom_key);
	vec = (struct bloom_keyvec *)xcalloc(1, sz);
	if (!vec)
		return NULL;
	vec->count = nr;

	bloom_key_fill(&vec->key[0], path, len, settings);
	nr = 1;
	p = path + len - 1;
	while (p > path) {
		if (*p == '/') {
			bloom_key_fill(&vec->key[nr++], path, p - path, settings);
		}
		p--;
	}
	assert(nr == vec->count);
	return vec;
}

void bloom_keyvec_free(struct bloom_keyvec *vec)
{
	if (!vec)
		return;
	for (size_t nr = 0; nr < vec->count; nr++)
		bloom_key_clear(&vec->key[nr]);
	free(vec);
}

static int pathmap_cmp(const void *hashmap_cmp_fn_data UNUSED,
		       const struct hashmap_entry *eptr,
		       const struct hashmap_entry *entry_or_key,
		       const void *keydata UNUSED)
{
	const struct pathmap_hash_entry *e1, *e2;

	e1 = container_of(eptr, const struct pathmap_hash_entry, entry);
	e2 = container_of(entry_or_key, const struct pathmap_hash_entry, entry);

	return strcmp(e1->path, e2->path);
}

static void init_truncated_large_filter(struct bloom_filter *filter,
					int version)
{
	filter->data = filter->to_free = xmalloc(1);
	filter->data[0] = 0xFF;
	filter->len = 1;
	filter->version = version;
}

#define VISITED   (1u<<21)
#define HIGH_BITS (1u<<22)

static int has_entries_with_high_bit(struct repository *r, struct tree *t)
{
	if (repo_parse_tree(r, t))
		return 1;

	if (!(t->object.flags & VISITED)) {
		struct tree_desc desc;
		struct name_entry entry;

		init_tree_desc(&desc, &t->object.oid, t->buffer, t->size);
		while (tree_entry(&desc, &entry)) {
			size_t i;
			for (i = 0; i < entry.pathlen; i++) {
				if (entry.path[i] & 0x80) {
					t->object.flags |= HIGH_BITS;
					goto done;
				}
			}

			if (S_ISDIR(entry.mode)) {
				struct tree *sub = lookup_tree(r, &entry.oid);
				if (sub && has_entries_with_high_bit(r, sub)) {
					t->object.flags |= HIGH_BITS;
					goto done;
				}
			}

		}

done:
		t->object.flags |= VISITED;
	}

	return !!(t->object.flags & HIGH_BITS);
}

static int commit_tree_has_high_bit_paths(struct repository *r,
					  struct commit *c)
{
	struct tree *t;
	if (repo_parse_commit(r, c))
		return 1;
	t = repo_get_commit_tree(r, c);
	if (!t)
		return 1;
	return has_entries_with_high_bit(r, t);
}

static struct bloom_filter *upgrade_filter(struct repository *r, struct commit *c,
					   struct bloom_filter *filter,
					   int hash_version)
{
	struct commit_list *p = c->parents;
	if (commit_tree_has_high_bit_paths(r, c))
		return NULL;

	if (p && commit_tree_has_high_bit_paths(r, p->item))
		return NULL;

	filter->version = hash_version;

	return filter;
}

struct bloom_filter *get_bloom_filter(struct repository *r, struct commit *c)
{
	struct bloom_filter *filter;
	int hash_version;

	filter = get_or_compute_bloom_filter(r, c, 0, NULL, NULL);
	if (!filter)
		return NULL;

	prepare_repo_settings(r);
	hash_version = r->settings.commit_graph_changed_paths_version;

	if (!(hash_version == -1 || hash_version == filter->version))
		return NULL; /* unusable filter */
	return filter;
}

struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
						 struct commit *c,
						 int compute_if_not_present,
						 const struct bloom_filter_settings *settings,
						 enum bloom_filter_computed *computed)
{
	struct bloom_filter *filter;
	int i;
	struct diff_options diffopt;

	if (computed)
		*computed = BLOOM_NOT_COMPUTED;

	if (!bloom_filters.slab_size)
		return NULL;

	filter = bloom_filter_slab_at(&bloom_filters, c);

	if (!filter->data) {
		struct commit_graph *g;
		uint32_t graph_pos;

		g = repo_find_commit_pos_in_graph(r, c, &graph_pos);
		if (g)
			load_bloom_filter_from_graph(g, filter, graph_pos);
	}

	if (filter->data && filter->len) {
		struct bloom_filter *upgrade;
		if (!settings || settings->hash_version == filter->version)
			return filter;

		/* version mismatch, see if we can upgrade */
		if (compute_if_not_present &&
		    git_env_bool("GIT_TEST_UPGRADE_BLOOM_FILTERS", 1)) {
			upgrade = upgrade_filter(r, c, filter,
						 settings->hash_version);
			if (upgrade) {
				if (computed)
					*computed |= BLOOM_UPGRADED;
				return upgrade;
			}
		}
	}
	if (!compute_if_not_present)
		return NULL;

	repo_diff_setup(r, &diffopt);
	diffopt.flags.recursive = 1;
	diffopt.detect_rename = 0;
	diffopt.max_changes = settings->max_changed_paths;
	diff_setup_done(&diffopt);

	/* ensure commit is parsed so we have parent information */
	repo_parse_commit(r, c);

	if (c->parents)
		diff_tree_oid(&c->parents->item->object.oid, &c->object.oid, "", &diffopt);
	else
		diff_tree_oid(NULL, &c->object.oid, "", &diffopt);
	diffcore_std(&diffopt);

	if (diff_queued_diff.nr <= settings->max_changed_paths) {
		struct hashmap pathmap = HASHMAP_INIT(pathmap_cmp, NULL);
		struct pathmap_hash_entry *e;
		struct hashmap_iter iter;

		for (i = 0; i < diff_queued_diff.nr; i++) {
			char *path = diff_queued_diff.queue[i]->two->path;

			/*
			 * Add each leading directory of the changed file, i.e. for
			 * 'dir/subdir/file' add 'dir' and 'dir/subdir' as well, so
			 * the Bloom filter could be used to speed up commands like
			 * 'git log dir/subdir', too.
			 *
			 * Note that directories are added without the trailing '/'.
			 */
			do {
				char *last_slash = strrchr(path, '/');

				FLEX_ALLOC_STR(e, path, path);
				hashmap_entry_init(&e->entry, strhash(path));

				if (!hashmap_get(&pathmap, &e->entry, NULL))
					hashmap_add(&pathmap, &e->entry);
				else
					free(e);

				if (!last_slash)
					last_slash = path;
				*last_slash = '\0';

			} while (*path);
		}

		if (hashmap_get_size(&pathmap) > settings->max_changed_paths) {
			init_truncated_large_filter(filter,
						    settings->hash_version);
			if (computed)
				*computed |= BLOOM_TRUNC_LARGE;
			goto cleanup;
		}

		filter->len = (hashmap_get_size(&pathmap) * settings->bits_per_entry + BITS_PER_WORD - 1) / BITS_PER_WORD;
		filter->version = settings->hash_version;
		if (!filter->len) {
			if (computed)
				*computed |= BLOOM_TRUNC_EMPTY;
			filter->len = 1;
		}
		CALLOC_ARRAY(filter->data, filter->len);
		filter->to_free = filter->data;

		hashmap_for_each_entry(&pathmap, &iter, e, entry) {
			struct bloom_key key;
			bloom_key_fill(&key, e->path, strlen(e->path), settings);
			add_key_to_filter(&key, filter, settings);
			bloom_key_clear(&key);
		}

	cleanup:
		hashmap_clear_and_free(&pathmap, struct pathmap_hash_entry, entry);
	} else {
		init_truncated_large_filter(filter, settings->hash_version);

		if (computed)
			*computed |= BLOOM_TRUNC_LARGE;
	}

	if (computed)
		*computed |= BLOOM_COMPUTED;

	diff_queue_clear(&diff_queued_diff);
	return filter;
}

int bloom_filter_contains(const struct bloom_filter *filter,
			  const struct bloom_key *key,
			  const struct bloom_filter_settings *settings)
{
	int i;
	uint64_t mod = filter->len * BITS_PER_WORD;

	if (!mod)
		return -1;

	for (i = 0; i < settings->num_hashes; i++) {
		uint64_t hash_mod = key->hashes[i] % mod;
		uint64_t block_pos = hash_mod / BITS_PER_WORD;
		if (!(filter->data[block_pos] & get_bitmask(hash_mod)))
			return 0;
	}

	return 1;
}

int bloom_filter_contains_vec(const struct bloom_filter *filter,
			      const struct bloom_keyvec *vec,
			      const struct bloom_filter_settings *settings)
{
	int ret = 1;

	for (size_t nr = 0; ret > 0 && nr < vec->count; nr++)
		ret = bloom_filter_contains(filter, &vec->key[nr], settings);

	return ret;
}

uint32_t test_bloom_murmur3_seeded(uint32_t seed, const char *data, size_t len,
				   int version)
{
	assert(version == 1 || version == 2);

	if (version == 2)
		return murmur3_seeded_v2(seed, data, len);
	else
		return murmur3_seeded_v1(seed, data, len);
}
