/*
 * GIT - the stupid content tracker
 *
 * Copyright (c) Junio C Hamano, 2006
 */
#include "cache.h"
#include "strbuf.h"
#include "quote.h"
#include "tree.h"

static struct treeent {
	unsigned mode;
	unsigned char sha1[20];
	int len;
	char name[FLEX_ARRAY];
} **entries;
static int alloc, used;

static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
{
	struct treeent *ent;
	int len = strlen(path);
	if (strchr(path, '/'))
		die("path %s contains slash", path);

	if (alloc <= used) {
		alloc = alloc_nr(used);
		entries = xrealloc(entries, sizeof(*entries) * alloc);
	}
	ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1);
	ent->mode = mode;
	ent->len = len;
	hashcpy(ent->sha1, sha1);
	memcpy(ent->name, path, len+1);
}

static int ent_compare(const void *a_, const void *b_)
{
	struct treeent *a = *(struct treeent **)a_;
	struct treeent *b = *(struct treeent **)b_;
	return base_name_compare(a->name, a->len, a->mode,
				 b->name, b->len, b->mode);
}

static void write_tree(unsigned char *sha1)
{
	char *buffer;
	unsigned long size, offset;
	int i;

	qsort(entries, used, sizeof(*entries), ent_compare);
	for (size = i = 0; i < used; i++)
		size += 32 + entries[i]->len;
	buffer = xmalloc(size);
	offset = 0;

	for (i = 0; i < used; i++) {
		struct treeent *ent = entries[i];

		if (offset + ent->len + 100 < size) {
			size = alloc_nr(offset + ent->len + 100);
			buffer = xrealloc(buffer, size);
		}
		offset += sprintf(buffer + offset, "%o ", ent->mode);
		offset += sprintf(buffer + offset, "%s", ent->name);
		buffer[offset++] = 0;
		hashcpy((unsigned char*)buffer + offset, ent->sha1);
		offset += 20;
	}
	write_sha1_file(buffer, offset, tree_type, sha1);
}

static const char mktree_usage[] = "git-mktree [-z]";

int main(int ac, char **av)
{
	struct strbuf sb;
	unsigned char sha1[20];
	int line_termination = '\n';

	setup_git_directory();

	while ((1 < ac) && av[1][0] == '-') {
		char *arg = av[1];
		if (!strcmp("-z", arg))
			line_termination = 0;
		else
			usage(mktree_usage);
		ac--;
		av++;
	}

	strbuf_init(&sb);
	while (1) {
		int len;
		char *ptr, *ntr;
		unsigned mode;
		char type[20];
		char *path;

		read_line(&sb, stdin, line_termination);
		if (sb.eof)
			break;
		len = sb.len;
		ptr = sb.buf;
		/* Input is non-recursive ls-tree output format
		 * mode SP type SP sha1 TAB name
		 */
		mode = strtoul(ptr, &ntr, 8);
		if (ptr == ntr || !ntr || *ntr != ' ')
			die("input format error: %s", sb.buf);
		ptr = ntr + 1; /* type */
		ntr = strchr(ptr, ' ');
		if (!ntr || sb.buf + len <= ntr + 41 ||
		    ntr[41] != '\t' ||
		    get_sha1_hex(ntr + 1, sha1))
			die("input format error: %s", sb.buf);
		if (sha1_object_info(sha1, type, NULL))
			die("object %s unavailable", sha1_to_hex(sha1));
		*ntr++ = 0; /* now at the beginning of SHA1 */
		if (strcmp(ptr, type))
			die("object type %s mismatch (%s)", ptr, type);
		ntr += 41; /* at the beginning of name */
		if (line_termination && ntr[0] == '"')
			path = unquote_c_style(ntr, NULL);
		else
			path = ntr;

		append_to_tree(mode, sha1, path);

		if (path != ntr)
			free(path);
	}
	write_tree(sha1);
	puts(sha1_to_hex(sha1));
	exit(0);
}
