#define _XOPEN_SOURCE /* glibc2 needs this */
#include <time.h>
#include <ctype.h>
#include "cache.h"

struct entry {
	unsigned char old_sha1[20];
	unsigned char new_sha1[20];
	int converted;
};

#define MAXOBJECTS (1000000)

static struct entry *convert[MAXOBJECTS];
static int nr_convert;

static struct entry * convert_entry(unsigned char *sha1);

static struct entry *insert_new(unsigned char *sha1, int pos)
{
	struct entry *new = xmalloc(sizeof(struct entry));
	memset(new, 0, sizeof(*new));
	memcpy(new->old_sha1, sha1, 20);
	memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
	convert[pos] = new;
	nr_convert++;
	if (nr_convert == MAXOBJECTS)
		die("you're kidding me - hit maximum object limit");
	return new;
}

static struct entry *lookup_entry(unsigned char *sha1)
{
	int low = 0, high = nr_convert;

	while (low < high) {
		int next = (low + high) / 2;
		struct entry *n = convert[next];
		int cmp = memcmp(sha1, n->old_sha1, 20);
		if (!cmp)
			return n;
		if (cmp < 0) {
			high = next;
			continue;
		}
		low = next+1;
	}
	return insert_new(sha1, low);
}

static void convert_binary_sha1(void *buffer)
{
	struct entry *entry = convert_entry(buffer);
	memcpy(buffer, entry->new_sha1, 20);
}

static void convert_ascii_sha1(void *buffer)
{
	unsigned char sha1[20];
	struct entry *entry;

	if (get_sha1_hex(buffer, sha1))
		die("bad sha1");
	entry = convert_entry(sha1);
	memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
}

static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
{
	char *new = xmalloc(size);
	unsigned long newlen = 0;
	unsigned long used;

	used = 0;
	while (size) {
		int len = 21 + strlen(buffer);
		char *path = strchr(buffer, ' ');
		unsigned char *sha1;
		unsigned int mode;
		char *slash, *origpath;

		if (!path || sscanf(buffer, "%o", &mode) != 1)
			die("bad tree conversion");
		path++;
		if (memcmp(path, base, baselen))
			break;
		origpath = path;
		path += baselen;
		slash = strchr(path, '/');
		if (!slash) {
			newlen += sprintf(new + newlen, "%o %s", mode, path);
			new[newlen++] = '\0';
			memcpy(new + newlen, buffer + len - 20, 20);
			newlen += 20;

			used += len;
			size -= len;
			buffer += len;
			continue;
		}

		newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, slash - path, path);
		new[newlen++] = 0;
		sha1 = (unsigned char *)(new + newlen);
		newlen += 20;

		len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);

		used += len;
		size -= len;
		buffer += len;
	}

	write_sha1_file(new, newlen, "tree", result_sha1);
	free(new);
	return used;
}

static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
{
	void *orig_buffer = buffer;
	unsigned long orig_size = size;

	while (size) {
		int len = 1+strlen(buffer);

		convert_binary_sha1(buffer + len);

		len += 20;
		if (len > size)
			die("corrupt tree object");
		size -= len;
		buffer += len;
	}

	write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
}

static unsigned long parse_oldstyle_date(const char *buf)
{
	char c, *p;
	char buffer[100];
	struct tm tm;
	const char *formats[] = {
		"%c",
		"%a %b %d %T",
		"%Z",
		"%Y",
		" %Y",
		NULL
	};
	/* We only ever did two timezones in the bad old format .. */
	const char *timezones[] = {
		"PDT", "PST", "CEST", NULL
	};
	const char **fmt = formats;

	p = buffer;
	while (isspace(c = *buf))
		buf++;
	while ((c = *buf++) != '\n')
		*p++ = c;
	*p++ = 0;
	buf = buffer;
	memset(&tm, 0, sizeof(tm));
	do {
		const char *next = strptime(buf, *fmt, &tm);
		if (next) {
			if (!*next)
				return mktime(&tm);
			buf = next;
		} else {
			const char **p = timezones;
			while (isspace(*buf))
				buf++;
			while (*p) {
				if (!memcmp(buf, *p, strlen(*p))) {
					buf += strlen(*p);
					break;
				}
				p++;
			}
		}
		fmt++;
	} while (*buf && *fmt);
	printf("left: %s\n", buf);
	return mktime(&tm);				
}

static int convert_date_line(char *dst, void **buf, unsigned long *sp)
{
	unsigned long size = *sp;
	char *line = *buf;
	char *next = strchr(line, '\n');
	char *date = strchr(line, '>');
	int len;

	if (!next || !date)
		die("missing or bad author/committer line %s", line);
	next++; date += 2;

	*buf = next;
	*sp = size - (next - line);

	len = date - line;
	memcpy(dst, line, len);
	dst += len;

	/* Is it already in new format? */
	if (isdigit(*date)) {
		int datelen = next - date;
		memcpy(dst, date, datelen);
		return len + datelen;
	}

	/*
	 * Hacky hacky: one of the sparse old-style commits does not have
	 * any date at all, but we can fake it by using the committer date.
	 */
	if (*date == '\n' && strchr(next, '>'))
		date = strchr(next, '>')+2;

	return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
}

static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
{
	char *new = xmalloc(size + 100);
	unsigned long newlen = 0;
	
	// "tree <sha1>\n"
	memcpy(new + newlen, buffer, 46);
	newlen += 46;
	buffer += 46;
	size -= 46;

	// "parent <sha1>\n"
	while (!memcmp(buffer, "parent ", 7)) {
		memcpy(new + newlen, buffer, 48);
		newlen += 48;
		buffer += 48;
		size -= 48;
	}

	// "author xyz <xyz> date"
	newlen += convert_date_line(new + newlen, &buffer, &size);
	// "committer xyz <xyz> date"
	newlen += convert_date_line(new + newlen, &buffer, &size);

	// Rest
	memcpy(new + newlen, buffer, size);
	newlen += size;

	write_sha1_file(new, newlen, "commit", result_sha1);
	free(new);	
}

static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
{
	void *orig_buffer = buffer;
	unsigned long orig_size = size;

	convert_ascii_sha1(buffer+5);
	buffer += 46;    /* "tree " + "hex sha1" + "\n" */
	while (!memcmp(buffer, "parent ", 7)) {
		convert_ascii_sha1(buffer+7);
		buffer += 48;
	}
	convert_date(orig_buffer, orig_size, result_sha1);
}

static struct entry * convert_entry(unsigned char *sha1)
{
	struct entry *entry = lookup_entry(sha1);
	char type[20];
	void *buffer, *data;
	unsigned long size;

	if (entry->converted)
		return entry;
	data = read_sha1_file(sha1, type, &size);
	if (!data)
		die("unable to read object %s", sha1_to_hex(sha1));

	buffer = xmalloc(size);
	memcpy(buffer, data, size);
	
	if (!strcmp(type, "blob")) {
		write_sha1_file(buffer, size, "blob", entry->new_sha1);
	} else if (!strcmp(type, "tree"))
		convert_tree(buffer, size, entry->new_sha1);
	else if (!strcmp(type, "commit"))
		convert_commit(buffer, size, entry->new_sha1);
	else
		die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
	entry->converted = 1;
	free(buffer);
	return entry;
}

int main(int argc, char **argv)
{
	unsigned char sha1[20];
	struct entry *entry;

	if (argc != 2 || get_sha1_hex(argv[1], sha1))
		usage("convert-cache <sha1>");

	entry = convert_entry(sha1);
	printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
	return 0;
}
