/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
#include "git2/object.h"
#include "git2/sys/odb_backend.h"
#include "fileops.h"
#include "hash.h"
#include "odb.h"
#include "array.h"
#include "oidmap.h"

#include "git2/odb_backend.h"
#include "git2/types.h"
#include "git2/pack.h"

struct memobject {
	git_oid oid;
	size_t len;
	git_otype type;
	char data[GIT_FLEX_ARRAY];
};

struct memory_packer_db {
	git_odb_backend parent;
	git_oidmap *objects;
	git_array_t(struct memobject *) commits;
};

static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
{
	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
	struct memobject *obj = NULL; 
	khiter_t pos;
	size_t alloc_len;
	int rval;

	pos = git_oidmap_put(db->objects, oid, &rval);
	if (rval < 0)
		return -1;

	if (rval == 0)
		return 0;

	GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
	obj = git__malloc(alloc_len);
	GITERR_CHECK_ALLOC(obj);

	memcpy(obj->data, data, len);
	git_oid_cpy(&obj->oid, oid);
	obj->len = len;
	obj->type = type;

	git_oidmap_set_key_at(db->objects, pos, &obj->oid);
	git_oidmap_set_value_at(db->objects, pos, obj);

	if (type == GIT_OBJ_COMMIT) {
		struct memobject **store = git_array_alloc(db->commits);
		GITERR_CHECK_ALLOC(store);
		*store = obj;
	}

	return 0;
}

static int impl__exists(git_odb_backend *backend, const git_oid *oid)
{
	struct memory_packer_db *db = (struct memory_packer_db *)backend;

	return git_oidmap_exists(db->objects, oid);
}

static int impl__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
{
	struct memory_packer_db *db = (struct memory_packer_db *)backend;
	struct memobject *obj = NULL;
	khiter_t pos;

	pos = git_oidmap_lookup_index(db->objects, oid);
	if (!git_oidmap_valid_index(db->objects, pos))
		return GIT_ENOTFOUND;

	obj = git_oidmap_value_at(db->objects, pos);

	*len_p = obj->len;
	*type_p = obj->type;
	*buffer_p = git__malloc(obj->len);
	GITERR_CHECK_ALLOC(*buffer_p);

	memcpy(*buffer_p, obj->data, obj->len);
	return 0;
}

static int impl__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
{
	struct memory_packer_db *db = (struct memory_packer_db *)backend;
	struct memobject *obj = NULL;
	khiter_t pos;

	pos = git_oidmap_lookup_index(db->objects, oid);
	if (!git_oidmap_valid_index(db->objects, pos))
		return GIT_ENOTFOUND;

	obj = git_oidmap_value_at(db->objects, pos);

	*len_p = obj->len;
	*type_p = obj->type;
	return 0;
}

int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_backend)
{
	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
	git_packbuilder *packbuilder;
	uint32_t i;
	int err = -1;

	if (git_packbuilder_new(&packbuilder, repo) < 0)
		return -1;

	for (i = 0; i < db->commits.size; ++i) {
		struct memobject *commit = db->commits.ptr[i];

		err = git_packbuilder_insert_commit(packbuilder, &commit->oid);
		if (err < 0)
			goto cleanup;
	}

	err = git_packbuilder_write_buf(pack, packbuilder);

cleanup:
	git_packbuilder_free(packbuilder);
	return err;
}

void git_mempack_reset(git_odb_backend *_backend)
{
	struct memory_packer_db *db = (struct memory_packer_db *)_backend;
	struct memobject *object = NULL;

	git_oidmap_foreach_value(db->objects, object, {
		git__free(object);
	});

	git_array_clear(db->commits);

	git_oidmap_clear(db->objects);
}

static void impl__free(git_odb_backend *_backend)
{
	struct memory_packer_db *db = (struct memory_packer_db *)_backend;

	git_oidmap_free(db->objects);
	git__free(db);
}

int git_mempack_new(git_odb_backend **out)
{
	struct memory_packer_db *db;

	assert(out);

	db = git__calloc(1, sizeof(struct memory_packer_db));
	GITERR_CHECK_ALLOC(db);

	db->objects = git_oidmap_alloc();

	db->parent.version = GIT_ODB_BACKEND_VERSION;
	db->parent.read = &impl__read;
	db->parent.write = &impl__write;
	db->parent.read_header = &impl__read_header;
	db->parent.exists = &impl__exists;
	db->parent.free = &impl__free;

	*out = (git_odb_backend *)db;
	return 0;
}
