#include "git-compat-util.h"
#include "hash.h"
#include "path.h"
#include "object-store.h"
#include "hex.h"
#include "repository.h"
#include "wrapper.h"
#include "gettext.h"
#include "loose.h"
#include "lockfile.h"
#include "oidtree.h"

static const char *loose_object_header = "# loose-object-idx\n";

static inline int should_use_loose_object_map(struct repository *repo)
{
	return repo->compat_hash_algo && repo->gitdir;
}

void loose_object_map_init(struct loose_object_map **map)
{
	struct loose_object_map *m;
	m = xmalloc(sizeof(**map));
	m->to_compat = kh_init_oid_map();
	m->to_storage = kh_init_oid_map();
	*map = m;
}

static int insert_oid_pair(kh_oid_map_t *map, const struct object_id *key, const struct object_id *value)
{
	khiter_t pos;
	int ret;
	struct object_id *stored;

	pos = kh_put_oid_map(map, *key, &ret);

	/* This item already exists in the map. */
	if (ret == 0)
		return 0;

	stored = xmalloc(sizeof(*stored));
	oidcpy(stored, value);
	kh_value(map, pos) = stored;
	return 1;
}

static int insert_loose_map(struct object_directory *odb,
			    const struct object_id *oid,
			    const struct object_id *compat_oid)
{
	struct loose_object_map *map = odb->loose_map;
	int inserted = 0;

	inserted |= insert_oid_pair(map->to_compat, oid, compat_oid);
	inserted |= insert_oid_pair(map->to_storage, compat_oid, oid);
	if (inserted)
		oidtree_insert(odb->loose_objects_cache, compat_oid);

	return inserted;
}

static int load_one_loose_object_map(struct repository *repo, struct object_directory *dir)
{
	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
	FILE *fp;

	if (!dir->loose_map)
		loose_object_map_init(&dir->loose_map);
	if (!dir->loose_objects_cache) {
		ALLOC_ARRAY(dir->loose_objects_cache, 1);
		oidtree_init(dir->loose_objects_cache);
	}

	insert_loose_map(dir, repo->hash_algo->empty_tree, repo->compat_hash_algo->empty_tree);
	insert_loose_map(dir, repo->hash_algo->empty_blob, repo->compat_hash_algo->empty_blob);
	insert_loose_map(dir, repo->hash_algo->null_oid, repo->compat_hash_algo->null_oid);

	repo_common_path_replace(repo, &path, "objects/loose-object-idx");
	fp = fopen(path.buf, "rb");
	if (!fp) {
		strbuf_release(&path);
		return 0;
	}

	errno = 0;
	if (strbuf_getwholeline(&buf, fp, '\n') || strcmp(buf.buf, loose_object_header))
		goto err;
	while (!strbuf_getline_lf(&buf, fp)) {
		const char *p;
		struct object_id oid, compat_oid;
		if (parse_oid_hex_algop(buf.buf, &oid, &p, repo->hash_algo) ||
		    *p++ != ' ' ||
		    parse_oid_hex_algop(p, &compat_oid, &p, repo->compat_hash_algo) ||
		    p != buf.buf + buf.len)
			goto err;
		insert_loose_map(dir, &oid, &compat_oid);
	}

	strbuf_release(&buf);
	strbuf_release(&path);
	return errno ? -1 : 0;
err:
	strbuf_release(&buf);
	strbuf_release(&path);
	return -1;
}

int repo_read_loose_object_map(struct repository *repo)
{
	struct object_directory *dir;

	if (!should_use_loose_object_map(repo))
		return 0;

	prepare_alt_odb(repo);

	for (dir = repo->objects->odb; dir; dir = dir->next) {
		if (load_one_loose_object_map(repo, dir) < 0) {
			return -1;
		}
	}
	return 0;
}

int repo_write_loose_object_map(struct repository *repo)
{
	kh_oid_map_t *map = repo->objects->odb->loose_map->to_compat;
	struct lock_file lock;
	int fd;
	khiter_t iter;
	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;

	if (!should_use_loose_object_map(repo))
		return 0;

	repo_common_path_replace(repo, &path, "objects/loose-object-idx");
	fd = hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1);
	iter = kh_begin(map);
	if (write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0)
		goto errout;

	for (; iter != kh_end(map); iter++) {
		if (kh_exist(map, iter)) {
			if (oideq(&kh_key(map, iter), repo->hash_algo->empty_tree) ||
			    oideq(&kh_key(map, iter), repo->hash_algo->empty_blob))
				continue;
			strbuf_addf(&buf, "%s %s\n", oid_to_hex(&kh_key(map, iter)), oid_to_hex(kh_value(map, iter)));
			if (write_in_full(fd, buf.buf, buf.len) < 0)
				goto errout;
			strbuf_reset(&buf);
		}
	}
	strbuf_release(&buf);
	if (commit_lock_file(&lock) < 0) {
		error_errno(_("could not write loose object index %s"), path.buf);
		strbuf_release(&path);
		return -1;
	}
	strbuf_release(&path);
	return 0;
errout:
	rollback_lock_file(&lock);
	strbuf_release(&buf);
	error_errno(_("failed to write loose object index %s"), path.buf);
	strbuf_release(&path);
	return -1;
}

static int write_one_object(struct repository *repo, const struct object_id *oid,
			    const struct object_id *compat_oid)
{
	struct lock_file lock;
	int fd;
	struct stat st;
	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;

	repo_common_path_replace(repo, &path, "objects/loose-object-idx");
	hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1);

	fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666);
	if (fd < 0)
		goto errout;
	if (fstat(fd, &st) < 0)
		goto errout;
	if (!st.st_size && write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0)
		goto errout;

	strbuf_addf(&buf, "%s %s\n", oid_to_hex(oid), oid_to_hex(compat_oid));
	if (write_in_full(fd, buf.buf, buf.len) < 0)
		goto errout;
	if (close(fd))
		goto errout;
	adjust_shared_perm(repo, path.buf);
	rollback_lock_file(&lock);
	strbuf_release(&buf);
	strbuf_release(&path);
	return 0;
errout:
	error_errno(_("failed to write loose object index %s"), path.buf);
	close(fd);
	rollback_lock_file(&lock);
	strbuf_release(&buf);
	strbuf_release(&path);
	return -1;
}

int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid,
			      const struct object_id *compat_oid)
{
	int inserted = 0;

	if (!should_use_loose_object_map(repo))
		return 0;

	inserted = insert_loose_map(repo->objects->odb, oid, compat_oid);
	if (inserted)
		return write_one_object(repo, oid, compat_oid);
	return 0;
}

int repo_loose_object_map_oid(struct repository *repo,
			      const struct object_id *src,
			      const struct git_hash_algo *to,
			      struct object_id *dest)
{
	struct object_directory *dir;
	kh_oid_map_t *map;
	khiter_t pos;

	for (dir = repo->objects->odb; dir; dir = dir->next) {
		struct loose_object_map *loose_map = dir->loose_map;
		if (!loose_map)
			continue;
		map = (to == repo->compat_hash_algo) ?
			loose_map->to_compat :
			loose_map->to_storage;
		pos = kh_get_oid_map(map, *src);
		if (pos < kh_end(map)) {
			oidcpy(dest, kh_value(map, pos));
			return 0;
		}
	}
	return -1;
}

void loose_object_map_clear(struct loose_object_map **map)
{
	struct loose_object_map *m = *map;
	struct object_id *oid;

	if (!m)
		return;

	kh_foreach_value(m->to_compat, oid, free(oid));
	kh_foreach_value(m->to_storage, oid, free(oid));
	kh_destroy_oid_map(m->to_compat);
	kh_destroy_oid_map(m->to_storage);
	free(m);
	*map = NULL;
}
