#include "git-compat-util.h"
#include "hash.h"
#include "path.h"
#include "object-store.h"
#include "hex.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);

	strbuf_git_common_path(&path, repo, "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;

	strbuf_git_common_path(&path, repo, "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), the_hash_algo->empty_tree) ||
			    oideq(&kh_key(map, iter), the_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\n"), 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;

	strbuf_git_common_path(&path, repo, "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(path.buf);
	rollback_lock_file(&lock);
	strbuf_release(&buf);
	strbuf_release(&path);
	return 0;
errout:
	error_errno(_("failed to write loose object index %s\n"), 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;
}
