#include "builtin.h"
#include "cache.h"
#include "commit.h"
#include "diff.h"
#include "path-list.h"
#include "revision.h"

static const char shortlog_usage[] =
"git-shortlog [-n] [-s] [<commit-id>... ]";

static char *common_repo_prefix;

static int compare_by_number(const void *a1, const void *a2)
{
	const struct path_list_item *i1 = a1, *i2 = a2;
	const struct path_list *l1 = i1->util, *l2 = i2->util;

	if (l1->nr < l2->nr)
		return 1;
	else if (l1->nr == l2->nr)
		return 0;
	else
		return -1;
}

static struct path_list mailmap = {NULL, 0, 0, 0};

static int read_mailmap(const char *filename)
{
	char buffer[1024];
	FILE *f = fopen(filename, "r");

	if (f == NULL)
		return 1;
	while (fgets(buffer, sizeof(buffer), f) != NULL) {
		char *end_of_name, *left_bracket, *right_bracket;
		char *name, *email;
		int i;
		if (buffer[0] == '#') {
			static const char abbrev[] = "# repo-abbrev:";
			int abblen = sizeof(abbrev) - 1;
			int len = strlen(buffer);

			if (len && buffer[len - 1] == '\n')
				buffer[--len] = 0;
			if (!strncmp(buffer, abbrev, abblen)) {
				char *cp;

				if (common_repo_prefix)
					free(common_repo_prefix);
				common_repo_prefix = xmalloc(len);

				for (cp = buffer + abblen; isspace(*cp); cp++)
					; /* nothing */
				strcpy(common_repo_prefix, cp);
			}
			continue;
		}
		if ((left_bracket = strchr(buffer, '<')) == NULL)
			continue;
		if ((right_bracket = strchr(left_bracket + 1, '>')) == NULL)
			continue;
		if (right_bracket == left_bracket + 1)
			continue;
		for (end_of_name = left_bracket; end_of_name != buffer
				&& isspace(end_of_name[-1]); end_of_name--)
			/* keep on looking */
		if (end_of_name == buffer)
			continue;
		name = xmalloc(end_of_name - buffer + 1);
		strlcpy(name, buffer, end_of_name - buffer + 1);
		email = xmalloc(right_bracket - left_bracket);
		for (i = 0; i < right_bracket - left_bracket - 1; i++)
			email[i] = tolower(left_bracket[i + 1]);
		email[right_bracket - left_bracket - 1] = '\0';
		path_list_insert(email, &mailmap)->util = name;
	}
	fclose(f);
	return 0;
}

static int map_email(char *email, char *name, int maxlen)
{
	char *p;
	struct path_list_item *item;

	/* autocomplete common developers */
	p = strchr(email, '>');
	if (!p)
		return 0;

	*p = '\0';
	/* downcase the email address */
	for (p = email; *p; p++)
		*p = tolower(*p);
	item = path_list_lookup(email, &mailmap);
	if (item != NULL) {
		const char *realname = (const char *)item->util;
		strncpy(name, realname, maxlen);
		return 1;
	}
	return 0;
}

static void insert_author_oneline(struct path_list *list,
		const char *author, int authorlen,
		const char *oneline, int onelinelen)
{
	const char *dot3 = common_repo_prefix;
	char *buffer, *p;
	struct path_list_item *item;
	struct path_list *onelines;

	while (authorlen > 0 && isspace(author[authorlen - 1]))
		authorlen--;

	buffer = xmalloc(authorlen + 1);
	memcpy(buffer, author, authorlen);
	buffer[authorlen] = '\0';

	item = path_list_insert(buffer, list);
	if (item->util == NULL)
		item->util = xcalloc(1, sizeof(struct path_list));
	else
		free(buffer);

	if (!strncmp(oneline, "[PATCH", 6)) {
		char *eob = strchr(oneline, ']');

		if (eob) {
			while (isspace(eob[1]) && eob[1] != '\n')
				eob++;
			if (eob - oneline < onelinelen) {
				onelinelen -= eob - oneline;
				oneline = eob;
			}
		}
	}

	while (onelinelen > 0 && isspace(oneline[0])) {
		oneline++;
		onelinelen--;
	}

	while (onelinelen > 0 && isspace(oneline[onelinelen - 1]))
		onelinelen--;

	buffer = xmalloc(onelinelen + 1);
	memcpy(buffer, oneline, onelinelen);
	buffer[onelinelen] = '\0';

	if (dot3) {
		int dot3len = strlen(dot3);
		if (dot3len > 5) {
			while ((p = strstr(buffer, dot3)) != NULL) {
				int taillen = strlen(p) - dot3len;
				memcpy(p, "/.../", 5);
				memmove(p + 5, p + dot3len, taillen + 1);
			}
		}
	}

	onelines = item->util;
	if (onelines->nr >= onelines->alloc) {
		onelines->alloc = alloc_nr(onelines->nr);
		onelines->items = xrealloc(onelines->items,
				onelines->alloc
				* sizeof(struct path_list_item));
	}

	onelines->items[onelines->nr].util = NULL;
	onelines->items[onelines->nr++].path = buffer;
}

static void read_from_stdin(struct path_list *list)
{
	char buffer[1024];

	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
		char *bob;
		if ((buffer[0] == 'A' || buffer[0] == 'a') &&
				!strncmp(buffer + 1, "uthor: ", 7) &&
				(bob = strchr(buffer + 7, '<')) != NULL) {
			char buffer2[1024], offset = 0;

			if (map_email(bob + 1, buffer, sizeof(buffer)))
				bob = buffer + strlen(buffer);
			else {
				offset = 8;
				while (buffer + offset < bob &&
				       isspace(bob[-1]))
					bob--;
			}

			while (fgets(buffer2, sizeof(buffer2), stdin) &&
					buffer2[0] != '\n')
				; /* chomp input */
			if (fgets(buffer2, sizeof(buffer2), stdin)) {
				int l2 = strlen(buffer2);
				int i;
				for (i = 0; i < l2; i++)
					if (!isspace(buffer2[i]))
						break;
				insert_author_oneline(list,
						buffer + offset,
						bob - buffer - offset,
						buffer2 + i, l2 - i);
			}
		}
	}
}

static void get_from_rev(struct rev_info *rev, struct path_list *list)
{
	char scratch[1024];
	struct commit *commit;

	prepare_revision_walk(rev);
	while ((commit = get_revision(rev)) != NULL) {
		char *author = NULL, *oneline, *buffer;
		int authorlen = authorlen, onelinelen;

		/* get author and oneline */
		for (buffer = commit->buffer; buffer && *buffer != '\0' &&
				*buffer != '\n'; ) {
			char *eol = strchr(buffer, '\n');

			if (eol == NULL)
				eol = buffer + strlen(buffer);
			else
				eol++;

			if (!strncmp(buffer, "author ", 7)) {
				char *bracket = strchr(buffer, '<');

				if (bracket == NULL || bracket > eol)
					die("Invalid commit buffer: %s",
					    sha1_to_hex(commit->object.sha1));

				if (map_email(bracket + 1, scratch,
							sizeof(scratch))) {
					author = scratch;
					authorlen = strlen(scratch);
				} else {
					if (bracket[-1] == ' ')
						bracket--;

					author = buffer + 7;
					authorlen = bracket - buffer - 7;
				}
			}
			buffer = eol;
		}

		if (author == NULL)
			die ("Missing author: %s",
					sha1_to_hex(commit->object.sha1));

		if (buffer == NULL || *buffer == '\0') {
			oneline = "<none>";
			onelinelen = sizeof(oneline) + 1;
		} else {
			char *eol;

			oneline = buffer + 1;
			eol = strchr(oneline, '\n');
			if (eol == NULL)
				onelinelen = strlen(oneline);
			else
				onelinelen = eol - oneline;
		}

		insert_author_oneline(list,
				author, authorlen, oneline, onelinelen);
	}

}

int cmd_shortlog(int argc, const char **argv, const char *prefix)
{
	struct rev_info rev;
	struct path_list list = { NULL, 0, 0, 1 };
	int i, j, sort_by_number = 0, summary = 0;

	/* since -n is a shadowed rev argument, parse our args first */
	while (argc > 1) {
		if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered"))
			sort_by_number = 1;
		else if (!strcmp(argv[1], "-s") ||
				!strcmp(argv[1], "--summary"))
			summary = 1;
		else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
			usage(shortlog_usage);
		else
			break;
		argv++;
		argc--;
	}
	init_revisions(&rev, prefix);
	argc = setup_revisions(argc, argv, &rev, NULL);
	if (argc > 1)
		die ("unrecognized argument: %s", argv[1]);

	if (!access(".mailmap", R_OK))
		read_mailmap(".mailmap");

	if (rev.pending.nr == 0)
		read_from_stdin(&list);
	else
		get_from_rev(&rev, &list);

	if (sort_by_number)
		qsort(list.items, list.nr, sizeof(struct path_list_item),
			compare_by_number);

	for (i = 0; i < list.nr; i++) {
		struct path_list *onelines = list.items[i].util;

		if (summary) {
			printf("%s: %d\n", list.items[i].path, onelines->nr);
		} else {
			printf("%s (%d):\n", list.items[i].path, onelines->nr);
			for (j = onelines->nr - 1; j >= 0; j--)
				printf("      %s\n", onelines->items[j].path);
			printf("\n");
		}

		onelines->strdup_paths = 1;
		path_list_clear(onelines, 1);
		free(onelines);
		list.items[i].util = NULL;
	}

	list.strdup_paths = 1;
	path_list_clear(&list, 1);
	mailmap.strdup_paths = 1;
	path_list_clear(&mailmap, 1);

	return 0;
}

