#include "refs.h"
#include "cache.h"
#include "rev-cache.h"

struct rev_cache **rev_cache;
int nr_revs, alloc_revs;

struct rev_list_elem *rle_free;

#define BATCH_SIZE 512

int find_rev_cache(const unsigned char *sha1)
{
	int lo = 0, hi = nr_revs;
	while (lo < hi) {
		int mi = (lo + hi) / 2;
		struct rev_cache *ri = rev_cache[mi];
		int cmp = memcmp(sha1, ri->sha1, 20);
		if (!cmp)
			return mi;
		if (cmp < 0)
			hi = mi;
		else
			lo = mi + 1;
	}
	return -lo - 1;
}

static struct rev_list_elem *alloc_list_elem(void)
{
	struct rev_list_elem *rle;
	if (!rle_free) {
		int i;

		rle = xmalloc(sizeof(*rle) * BATCH_SIZE);
		for (i = 0; i < BATCH_SIZE - 1; i++) {
			rle[i].ri = NULL;
			rle[i].next = &rle[i + 1];
		}
		rle[BATCH_SIZE - 1].ri = NULL;
		rle[BATCH_SIZE - 1].next = NULL;
		rle_free = rle;
	}
	rle = rle_free;
	rle_free = rle->next;
	return rle;
}

static struct rev_cache *create_rev_cache(const unsigned char *sha1)
{
	struct rev_cache *ri;
	int pos = find_rev_cache(sha1);

	if (0 <= pos)
		return rev_cache[pos];
	pos = -pos - 1;
	if (alloc_revs <= ++nr_revs) {
		alloc_revs = alloc_nr(alloc_revs);
		rev_cache = xrealloc(rev_cache, sizeof(ri) * alloc_revs);
	}
	if (pos < nr_revs)
		memmove(rev_cache + pos + 1, rev_cache + pos,
			(nr_revs - pos - 1) * sizeof(ri));
	ri = xcalloc(1, sizeof(*ri));
	memcpy(ri->sha1, sha1, 20);
	rev_cache[pos] = ri;
	return ri;
}

static unsigned char last_sha1[20];

static void write_one_rev_cache(FILE *rev_cache_file, struct rev_cache *ri)
{
	unsigned char flag;
	struct rev_list_elem *rle;

	if (ri->written)
		return;

	if (ri->parsed) {
		/* We use last_sha1 compression only for the first parent;
		 * otherwise the resulting rev-cache would lose the parent
		 * order information.
		 */
		if (ri->parents &&
		    !memcmp(ri->parents->ri->sha1, last_sha1, 20))
			flag = (ri->num_parents - 1) | 0x80;
		else
			flag = ri->num_parents;

		fwrite(ri->sha1, 20, 1, rev_cache_file);
		fwrite(&flag, 1, 1, rev_cache_file);
		for (rle = ri->parents; rle; rle = rle->next) {
			if (flag & 0x80 && rle == ri->parents)
				continue;
			fwrite(rle->ri->sha1, 20, 1, rev_cache_file);
		}
		memcpy(last_sha1, ri->sha1, 20);
		ri->written = 1;
	}
	/* recursively write children depth first */
	for (rle = ri->children; rle; rle = rle->next)
		write_one_rev_cache(rev_cache_file, rle->ri);
}

void write_rev_cache(const char *newpath, const char *oldpath)
{
	/* write the following commit ancestry information in
	 * $GIT_DIR/info/rev-cache.
	 *
	 * The format is:
	 * 20-byte SHA1 (commit ID)
	 * 1-byte flag:
	 * - bit 0-6 records "number of parent commit SHA1s to
	 *   follow" (i.e. up to 127 children can be listed).
	 * - when the bit 7 is on, then "the entry immediately
	 *   before this entry is one of the parents of this
         *   commit".
	 * N x 20-byte SHA1 (parent commit IDs)
	 */
	FILE *rev_cache_file;
	int i;
	struct rev_cache *ri;

	if (!strcmp(newpath, oldpath)) {
		/* If we are doing it in place */
		rev_cache_file = fopen(newpath, "a");
	}
	else {
		char buf[8096];
		size_t sz;
		FILE *oldfp = fopen(oldpath, "r");
		rev_cache_file = fopen(newpath, "w");
		if (oldfp) {
			while (1) {
				sz = fread(buf, 1, sizeof(buf), oldfp);
				if (sz == 0)
					break;
				fwrite(buf, 1, sz, rev_cache_file);
			}
			fclose(oldfp);
		}
	}

	memset(last_sha1, 0, 20);

	/* Go through available rev_cache structures, starting from
	 * parentless ones first, so that we would get most out of
	 * last_sha1 optimization by the depth first behaviour of
	 * write_one_rev_cache().
	 */
	for (i = 0; i < nr_revs; i++) {
		ri = rev_cache[i];
		if (ri->num_parents)
			continue;
		write_one_rev_cache(rev_cache_file, ri);
	}
	/* Then the rest */
	for (i = 0; i < nr_revs; i++) {
		ri = rev_cache[i];
		write_one_rev_cache(rev_cache_file, ri);
	}
	fclose(rev_cache_file);
}

static void add_parent(struct rev_cache *child,
		       const unsigned char *parent_sha1)
{
	struct rev_cache *parent = create_rev_cache(parent_sha1);
	struct rev_list_elem *e = alloc_list_elem();

	/* Keep the parent list ordered in the same way the commit
	 * object records them.
	 */
	e->ri = parent;
	e->next = NULL;
	if (!child->parents_tail)
		child->parents = e;
	else
		child->parents_tail->next = e;
	child->parents_tail = e;
	child->num_parents++;

	/* There is no inherent order of the children so we just
	 * LIFO them together.
	 */
	e = alloc_list_elem();
	e->next = parent->children;
	parent->children = e;
	e->ri = child;
	parent->num_children++;
}

int read_rev_cache(const char *path, FILE *dumpfile, int dry_run)
{
	unsigned char *map;
	int fd;
	struct stat st;
	unsigned long ofs, len;
	struct rev_cache *ri = NULL;

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		if (dry_run)
			return error("cannot open %s", path);
		if (errno == ENOENT)
			return 0;
		return -1;
	}
	if (fstat(fd, &st)) {
		close(fd);
		return -1;
	}
	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (map == MAP_FAILED) {
		close(fd);
		return -1;
	}
	close(fd);

	memset(last_sha1, 0, 20);
	ofs = 0;
	len = st.st_size;
	while (ofs < len) {
		unsigned char sha1[20];
		int flag, cnt, i;
		if (len < ofs + 21)
			die("rev-cache too short");
		memcpy(sha1, map + ofs, 20);
		flag = map[ofs + 20];
		ofs += 21;
		cnt = (flag & 0x7f) + ((flag & 0x80) != 0);
		if (len < ofs + (flag & 0x7f) * 20)
			die("rev-cache too short to have %d more parents",
			    (flag & 0x7f));
		if (dumpfile)
			fprintf(dumpfile, "%s", sha1_to_hex(sha1));
		if (!dry_run) {
			ri = create_rev_cache(sha1);
			if (!ri)
				die("cannot create rev-cache for %s",
				    sha1_to_hex(sha1));
			ri->written = ri->parsed = 1;
		}
		i = 0;
		if (flag & 0x80) {
			if (!dry_run)
				add_parent(ri, last_sha1);
			if (dumpfile)
				fprintf(dumpfile, " %s",
					sha1_to_hex(last_sha1));
			i++;
		}
		while (i++ < cnt) {
			if (!dry_run)
				add_parent(ri, map + ofs);
			if (dumpfile)
				fprintf(dumpfile, " %s",
					sha1_to_hex(last_sha1));
			ofs += 20;
		}
		if (dumpfile)
			fprintf(dumpfile, "\n");
		memcpy(last_sha1, sha1, 20);
	}
	if (ofs != len)
		die("rev-cache truncated?");
	munmap(map, len);
	return 0;
}

int record_rev_cache(const unsigned char *sha1, FILE *dumpfile)
{
	unsigned char parent[20];
	char type[20];
	unsigned long size, ofs;
	unsigned int cnt, i;
	void *buf;
	struct rev_cache *ri;

	buf = read_sha1_file(sha1, type, &size);
	if (!buf)
		return error("%s: not found", sha1_to_hex(sha1));
	if (strcmp(type, "commit")) {
		free(buf);
		return error("%s: not a commit but a %s",
			     sha1_to_hex(sha1), type);
	}
	ri = create_rev_cache(sha1);
	if (ri->parsed)
		return 0;
	if (dumpfile)
		fprintf(dumpfile, "commit %s\n", sha1_to_hex(sha1));

	cnt = 0;
	ofs = 46; /* "tree " + hex-sha1 + "\n" */
	while (!memcmp(buf + ofs, "parent ", 7) &&
	       !get_sha1_hex(buf + ofs + 7, parent)) {
		ofs += 48;
		cnt++;
	}
	if (cnt * 48 + 46 != ofs) {
		free(buf);
		die("internal error in record_rev_cache");
	}

	ri = create_rev_cache(sha1);
	ri->parsed = 1;

	for (i = 0; i < cnt; i++) {
		unsigned char parent_sha1[20];

		ofs = 46 + i * 48 + 7;
		get_sha1_hex(buf + ofs, parent_sha1);
		add_parent(ri, parent_sha1);
		record_rev_cache(parent_sha1, dumpfile);
	}
	free(buf);
	return 0;
}
