#include "git-compat-util.h"
#include "environment.h"
#include "string-list.h"
#include "mailmap.h"
#include "object-name.h"
#include "odb.h"
#include "setup.h"
#include "config.h"

struct mailmap_info {
	char *name;
	char *email;
};

struct mailmap_entry {
	/* name and email for the simple mail-only case */
	char *name;
	char *email;

	/* name and email for the complex mail and name matching case */
	struct string_list namemap;
};

static void free_mailmap_info(void *p, const char *s UNUSED)
{
	struct mailmap_info *mi = (struct mailmap_info *)p;
	free(mi->name);
	free(mi->email);
	free(mi);
}

static void free_mailmap_entry(void *p, const char *s UNUSED)
{
	struct mailmap_entry *me = (struct mailmap_entry *)p;

	free(me->name);
	free(me->email);

	me->namemap.strdup_strings = 1;
	string_list_clear_func(&me->namemap, free_mailmap_info);
	free(me);
}

/*
 * On some systems (e.g. MinGW 4.0), string.h has _only_ inline
 * definition of strcasecmp and no non-inline implementation is
 * supplied anywhere, which is, eh, "unusual"; we cannot take an
 * address of such a function to store it in namemap.cmp.  This is
 * here as a workaround---do not assign strcasecmp directly to
 * namemap.cmp until we know no systems that matter have such an
 * "unusual" string.h.
 */
static int namemap_cmp(const char *a, const char *b)
{
	return strcasecmp(a, b);
}

static void add_mapping(struct string_list *map,
			char *new_name, char *new_email,
			char *old_name, char *old_email)
{
	struct mailmap_entry *me;
	struct string_list_item *item;

	if (!old_email) {
		old_email = new_email;
		new_email = NULL;
	}

	item = string_list_insert(map, old_email);
	if (item->util) {
		me = (struct mailmap_entry *)item->util;
	} else {
		CALLOC_ARRAY(me, 1);
		me->namemap.strdup_strings = 1;
		me->namemap.cmp = namemap_cmp;
		item->util = me;
	}

	if (!old_name) {
		/* Replace current name and new email for simple entry */
		if (new_name) {
			free(me->name);
			me->name = xstrdup(new_name);
		}
		if (new_email) {
			free(me->email);
			me->email = xstrdup(new_email);
		}
	} else {
		struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info));
		mi->name = xstrdup_or_null(new_name);
		mi->email = xstrdup_or_null(new_email);
		string_list_insert(&me->namemap, old_name)->util = mi;
	}
}

static char *parse_name_and_email(char *buffer, char **name,
				  char **email, int allow_empty_email)
{
	char *left, *right, *nstart, *nend;
	*name = *email = NULL;

	if (!(left = strchr(buffer, '<')))
		return NULL;
	if (!(right = strchr(left + 1, '>')))
		return NULL;
	if (!allow_empty_email && (left+1 == right))
		return NULL;

	/* remove whitespace from beginning and end of name */
	nstart = buffer;
	while (isspace(*nstart) && nstart < left)
		++nstart;
	nend = left-1;
	while (nend > nstart && isspace(*nend))
		--nend;

	*name = (nstart <= nend ? nstart : NULL);
	*email = left+1;
	*(nend+1) = '\0';
	*right++ = '\0';

	return (*right == '\0' ? NULL : right);
}

static void read_mailmap_line(struct string_list *map, char *buffer)
{
	char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;

	if (buffer[0] == '#')
		return;

	if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)))
		parse_name_and_email(name2, &name2, &email2, 1);

	if (email1)
		add_mapping(map, name1, email1, name2, email2);
}

int read_mailmap_file(struct string_list *map, const char *filename,
		      unsigned flags)
{
	char buffer[1024];
	FILE *f;
	int fd;

	if (!filename)
		return 0;

	if (flags & MAILMAP_NOFOLLOW)
		fd = open_nofollow(filename, O_RDONLY);
	else
		fd = open(filename, O_RDONLY);

	if (fd < 0) {
		if (errno == ENOENT)
			return 0;
		return error_errno("unable to open mailmap at %s", filename);
	}
	f = xfdopen(fd, "r");

	while (fgets(buffer, sizeof(buffer), f) != NULL)
		read_mailmap_line(map, buffer);
	fclose(f);
	return 0;
}

static void read_mailmap_string(struct string_list *map, char *buf)
{
	while (*buf) {
		char *end = strchrnul(buf, '\n');

		if (*end)
			*end++ = '\0';

		read_mailmap_line(map, buf);
		buf = end;
	}
}

int read_mailmap_blob(struct repository *repo, struct string_list *map,
		      const char *name)
{
	struct object_id oid;
	char *buf;
	size_t size;
	enum object_type type;

	if (!name)
		return 0;
	if (repo_get_oid(repo, name, &oid) < 0)
		return 0;

	buf = odb_read_object(repo->objects, &oid, &type, &size);
	if (!buf)
		return error("unable to read mailmap object at %s", name);
	if (type != OBJ_BLOB) {
		free(buf);
		return error("mailmap is not a blob: %s", name);
	}

	read_mailmap_string(map, buf);

	free(buf);
	return 0;
}

int read_mailmap(struct repository *repo, struct string_list *map)
{
	int err = 0;
	char *mailmap_file = NULL, *mailmap_blob = NULL;

	repo_config_get_pathname(repo, "mailmap.file", &mailmap_file);
	repo_config_get_string(repo, "mailmap.blob", &mailmap_blob);

	map->strdup_strings = 1;
	map->cmp = namemap_cmp;

	if (!mailmap_blob && is_bare_repository(repo))
		mailmap_blob = xstrdup("HEAD:.mailmap");

	if (!startup_info->have_repository || !is_bare_repository(repo))
		err |= read_mailmap_file(map, ".mailmap",
					 startup_info->have_repository ?
					 MAILMAP_NOFOLLOW : 0);
	if (startup_info->have_repository)
		err |= read_mailmap_blob(repo, map, mailmap_blob);

	err |= read_mailmap_file(map, mailmap_file, 0);

	free(mailmap_file);
	free(mailmap_blob);

	return err;
}

void clear_mailmap(struct string_list *map)
{
	map->strdup_strings = 1;
	string_list_clear_func(map, free_mailmap_entry);
}

/*
 * Look for an entry in map that match string[0:len]; string[len]
 * does not have to be NUL (but it could be).
 */
static struct string_list_item *lookup_prefix(struct string_list *map,
					      const char *string, size_t len)
{
	bool exact_match;
	size_t i = string_list_find_insert_index(map, string, &exact_match);
	if (exact_match) {
		if (!string[len])
			return &map->items[i];
		/*
		 * that map entry matches exactly to the string, including
		 * the cruft at the end beyond "len".  That is not a match
		 * with string[0:len] that we are looking for.
		 */
	} else if (!string[len]) {
		/*
		 * asked with the whole string, and got nothing.  No
		 * matching entry can exist in the map.
		 */
		return NULL;
	}

	/*
	 * i is at the exact match to an overlong key, or location the
	 * overlong key would be inserted, which must come after the
	 * real location of the key if one exists.
	 */
	while (i-- && i < map->nr) {
		int cmp = strncasecmp(map->items[i].string, string, len);
		if (cmp < 0)
			/*
			 * "i" points at a key definitely below the prefix;
			 * the map does not have string[0:len] in it.
			 */
			break;
		else if (!cmp && !map->items[i].string[len])
			/* found it */
			return &map->items[i];
		/*
		 * otherwise, the string at "i" may be string[0:len]
		 * followed by a string that sorts later than string[len:];
		 * keep trying.
		 */
	}
	return NULL;
}

int map_user(struct string_list *map,
	     const char **email, size_t *emaillen,
	     const char **name, size_t *namelen)
{
	struct string_list_item *item;
	struct mailmap_entry *me;

	item = lookup_prefix(map, *email, *emaillen);
	if (item) {
		me = (struct mailmap_entry *)item->util;
		if (me->namemap.nr) {
			/*
			 * The item has multiple items, so we'll look up on
			 * name too. If the name is not found, we choose the
			 * simple entry.
			 */
			struct string_list_item *subitem;
			subitem = lookup_prefix(&me->namemap, *name, *namelen);
			if (subitem)
				item = subitem;
		}
	}
	if (item) {
		struct mailmap_info *mi = (struct mailmap_info *)item->util;
		if (mi->name == NULL && mi->email == NULL)
			return 0;
		if (mi->email) {
				*email = mi->email;
				*emaillen = strlen(*email);
		}
		if (mi->name) {
				*name = mi->name;
				*namelen = strlen(*name);
		}
		return 1;
	}
	return 0;
}
