/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "mailmap.h"

#include "common.h"
#include "path.h"
#include "repository.h"
#include "signature.h"
#include "git2/config.h"
#include "git2/revparse.h"
#include "blob.h"
#include "parse.h"

#define MM_FILE ".mailmap"
#define MM_FILE_CONFIG "mailmap.file"
#define MM_BLOB_CONFIG "mailmap.blob"
#define MM_BLOB_DEFAULT "HEAD:" MM_FILE

static void mailmap_entry_free(git_mailmap_entry *entry)
{
	if (!entry)
		return;

	git__free(entry->real_name);
	git__free(entry->real_email);
	git__free(entry->replace_name);
	git__free(entry->replace_email);
	git__free(entry);
}

/*
 * First we sort by replace_email, then replace_name (if present).
 * Entries with names are greater than entries without.
 */
static int mailmap_entry_cmp(const void *a_raw, const void *b_raw)
{
	const git_mailmap_entry *a = (const git_mailmap_entry *)a_raw;
	const git_mailmap_entry *b = (const git_mailmap_entry *)b_raw;
	int cmp;

	assert(a && b && a->replace_email && b->replace_email);

	cmp = git__strcmp(a->replace_email, b->replace_email);
	if (cmp)
		return cmp;

	/* NULL replace_names are less than not-NULL ones */
	if (a->replace_name == NULL || b->replace_name == NULL)
		return (int)(a->replace_name != NULL) - (int)(b->replace_name != NULL);

	return git__strcmp(a->replace_name, b->replace_name);
}

/* Replace the old entry with the new on duplicate. */
static int mailmap_entry_replace(void **old_raw, void *new_raw)
{
	mailmap_entry_free((git_mailmap_entry *)*old_raw);
	*old_raw = new_raw;
	return GIT_EEXISTS;
}

/* Check if we're at the end of line, w/ comments */
static bool is_eol(git_parse_ctx *ctx)
{
	char c;
	return git_parse_peek(&c, ctx, GIT_PARSE_PEEK_SKIP_WHITESPACE) < 0 || c == '#';
}

static int advance_until(
	const char **start, size_t *len, git_parse_ctx *ctx, char needle)
{
	*start = ctx->line;
	while (ctx->line_len > 0 && *ctx->line != '#' && *ctx->line != needle)
		git_parse_advance_chars(ctx, 1);

	if (ctx->line_len == 0 || *ctx->line == '#')
		return -1; /* end of line */

	*len = ctx->line - *start;
	git_parse_advance_chars(ctx, 1); /* advance past needle */
	return 0;
}

/*
 * Parse a single entry from a mailmap file.
 *
 * The output git_bufs will be non-owning, and should be copied before being
 * persisted.
 */
static int parse_mailmap_entry(
	git_buf *real_name, git_buf *real_email,
	git_buf *replace_name, git_buf *replace_email,
	git_parse_ctx *ctx)
{
	const char *start;
	size_t len;

	git_buf_clear(real_name);
	git_buf_clear(real_email);
	git_buf_clear(replace_name);
	git_buf_clear(replace_email);

	git_parse_advance_ws(ctx);
	if (is_eol(ctx))
		return -1; /* blank line */

	/* Parse the real name */
	if (advance_until(&start, &len, ctx, '<') < 0)
		return -1;

	git_buf_attach_notowned(real_name, start, len);
	git_buf_rtrim(real_name);

	/*
	 * If this is the last email in the line, this is the email to replace,
	 * otherwise, it's the real email.
	 */
	if (advance_until(&start, &len, ctx, '>') < 0)
		return -1;

	/* If we aren't at the end of the line, parse a second name and email */
	if (!is_eol(ctx)) {
		git_buf_attach_notowned(real_email, start, len);

		git_parse_advance_ws(ctx);
		if (advance_until(&start, &len, ctx, '<') < 0)
			return -1;
		git_buf_attach_notowned(replace_name, start, len);
		git_buf_rtrim(replace_name);

		if (advance_until(&start, &len, ctx, '>') < 0)
			return -1;
	}

	git_buf_attach_notowned(replace_email, start, len);

	if (!is_eol(ctx))
		return -1;

	return 0;
}

int git_mailmap_new(git_mailmap **out)
{
	int error;
	git_mailmap *mm = git__calloc(1, sizeof(git_mailmap));
	GIT_ERROR_CHECK_ALLOC(mm);

	error = git_vector_init(&mm->entries, 0, mailmap_entry_cmp);
	if (error < 0) {
		git__free(mm);
		return error;
	}
	*out = mm;
	return 0;
}

void git_mailmap_free(git_mailmap *mm)
{
	size_t idx;
	git_mailmap_entry *entry;
	if (!mm)
		return;

	git_vector_foreach(&mm->entries, idx, entry)
		mailmap_entry_free(entry);

	git_vector_free(&mm->entries);
	git__free(mm);
}

static int mailmap_add_entry_unterminated(
	git_mailmap *mm,
	const char *real_name, size_t real_name_size,
	const char *real_email, size_t real_email_size,
	const char *replace_name, size_t replace_name_size,
	const char *replace_email, size_t replace_email_size)
{
	int error;
	git_mailmap_entry *entry = git__calloc(1, sizeof(git_mailmap_entry));
	GIT_ERROR_CHECK_ALLOC(entry);

	assert(mm && replace_email && *replace_email);

	if (real_name_size > 0) {
		entry->real_name = git__substrdup(real_name, real_name_size);
		GIT_ERROR_CHECK_ALLOC(entry->real_name);
	}
	if (real_email_size > 0) {
		entry->real_email = git__substrdup(real_email, real_email_size);
		GIT_ERROR_CHECK_ALLOC(entry->real_email);
	}
	if (replace_name_size > 0) {
		entry->replace_name = git__substrdup(replace_name, replace_name_size);
		GIT_ERROR_CHECK_ALLOC(entry->replace_name);
	}
	entry->replace_email = git__substrdup(replace_email, replace_email_size);
	GIT_ERROR_CHECK_ALLOC(entry->replace_email);

	error = git_vector_insert_sorted(&mm->entries, entry, mailmap_entry_replace);
	if (error == GIT_EEXISTS)
		error = GIT_OK;
	else if (error < 0)
		mailmap_entry_free(entry);

	return error;
}

int git_mailmap_add_entry(
	git_mailmap *mm, const char *real_name, const char *real_email,
	const char *replace_name, const char *replace_email)
{
	return mailmap_add_entry_unterminated(
		mm,
		real_name, real_name ? strlen(real_name) : 0,
		real_email, real_email ? strlen(real_email) : 0,
		replace_name, replace_name ? strlen(replace_name) : 0,
		replace_email, strlen(replace_email));
}

static int mailmap_add_buffer(git_mailmap *mm, const char *buf, size_t len)
{
	int error = 0;
	git_parse_ctx ctx;

	/* Scratch buffers containing the real parsed names & emails */
	git_buf real_name = GIT_BUF_INIT;
	git_buf real_email = GIT_BUF_INIT;
	git_buf replace_name = GIT_BUF_INIT;
	git_buf replace_email = GIT_BUF_INIT;

	/* Buffers may not contain '\0's. */
	if (memchr(buf, '\0', len) != NULL)
		return -1;

	git_parse_ctx_init(&ctx, buf, len);

	/* Run the parser */
	while (ctx.remain_len > 0) {
		error = parse_mailmap_entry(
			&real_name, &real_email, &replace_name, &replace_email, &ctx);
		if (error < 0) {
			error = 0; /* Skip lines which don't contain a valid entry */
			git_parse_advance_line(&ctx);
			continue; /* TODO: warn */
		}

		/* NOTE: Can't use add_entry(...) as our buffers aren't terminated */
		error = mailmap_add_entry_unterminated(
			mm, real_name.ptr, real_name.size, real_email.ptr, real_email.size,
			replace_name.ptr, replace_name.size, replace_email.ptr, replace_email.size);
		if (error < 0)
			goto cleanup;

		error = 0;
	}

cleanup:
	git_buf_dispose(&real_name);
	git_buf_dispose(&real_email);
	git_buf_dispose(&replace_name);
	git_buf_dispose(&replace_email);
	return error;
}

int git_mailmap_from_buffer(git_mailmap **out, const char *data, size_t len)
{
	int error = git_mailmap_new(out);
	if (error < 0)
		return error;

	error = mailmap_add_buffer(*out, data, len);
	if (error < 0) {
		git_mailmap_free(*out);
		*out = NULL;
	}
	return error;
}

static int mailmap_add_blob(
	git_mailmap *mm, git_repository *repo, const char *rev)
{
	git_object *object = NULL;
	git_blob *blob = NULL;
	git_buf content = GIT_BUF_INIT;
	int error;

	assert(mm && repo);

	error = git_revparse_single(&object, repo, rev);
	if (error < 0)
		goto cleanup;

	error = git_object_peel((git_object **)&blob, object, GIT_OBJECT_BLOB);
	if (error < 0)
		goto cleanup;

	error = git_blob__getbuf(&content, blob);
	if (error < 0)
		goto cleanup;

	error = mailmap_add_buffer(mm, content.ptr, content.size);
	if (error < 0)
		goto cleanup;

cleanup:
	git_buf_dispose(&content);
	git_blob_free(blob);
	git_object_free(object);
	return error;
}

static int mailmap_add_file_ondisk(
	git_mailmap *mm, const char *path, git_repository *repo)
{
	const char *base = repo ? git_repository_workdir(repo) : NULL;
	git_buf fullpath = GIT_BUF_INIT;
	git_buf content = GIT_BUF_INIT;
	int error;

	error = git_path_join_unrooted(&fullpath, path, base, NULL);
	if (error < 0)
		goto cleanup;

	error = git_futils_readbuffer(&content, fullpath.ptr);
	if (error < 0)
		goto cleanup;

	error = mailmap_add_buffer(mm, content.ptr, content.size);
	if (error < 0)
		goto cleanup;

cleanup:
	git_buf_dispose(&fullpath);
	git_buf_dispose(&content);
	return error;
}

/* NOTE: Only expose with an error return, currently never errors */
static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo)
{
	git_config *config = NULL;
	git_buf rev_buf = GIT_BUF_INIT;
	git_buf path_buf = GIT_BUF_INIT;
	const char *rev = NULL;
	const char *path = NULL;

	assert(mm && repo);

	/* If we're in a bare repo, default blob to 'HEAD:.mailmap' */
	if (repo->is_bare)
		rev = MM_BLOB_DEFAULT;

	/* Try to load 'mailmap.file' and 'mailmap.blob' cfgs from the repo */
	if (git_repository_config(&config, repo) == 0) {
		if (git_config_get_string_buf(&rev_buf, config, MM_BLOB_CONFIG) == 0)
			rev = rev_buf.ptr;
		if (git_config_get_path(&path_buf, config, MM_FILE_CONFIG) == 0)
			path = path_buf.ptr;
	}

	/*
	 * Load mailmap files in order, overriding previous entries with new ones.
	 *  1. The '.mailmap' file in the repository's workdir root,
	 *  2. The blob described by the 'mailmap.blob' config (default HEAD:.mailmap),
	 *  3. The file described by the 'mailmap.file' config.
	 *
	 * We ignore errors from these loads, as these files may not exist, or may
	 * contain invalid information, and we don't want to report that error.
	 *
	 * XXX: Warn?
	 */
	if (!repo->is_bare)
		mailmap_add_file_ondisk(mm, MM_FILE, repo);
	if (rev != NULL)
		mailmap_add_blob(mm, repo, rev);
	if (path != NULL)
		mailmap_add_file_ondisk(mm, path, repo);

	git_buf_dispose(&rev_buf);
	git_buf_dispose(&path_buf);
	git_config_free(config);
}

int git_mailmap_from_repository(git_mailmap **out, git_repository *repo)
{
	int error = git_mailmap_new(out);
	if (error < 0)
		return error;
	mailmap_add_from_repository(*out, repo);
	return 0;
}

const git_mailmap_entry *git_mailmap_entry_lookup(
	const git_mailmap *mm, const char *name, const char *email)
{
	int error;
	ssize_t fallback = -1;
	size_t idx;
	git_mailmap_entry *entry;

	/* The lookup needle we want to use only sets the replace_email. */
	git_mailmap_entry needle = { NULL };
	needle.replace_email = (char *)email;

	assert(email);

	if (!mm)
		return NULL;

	/*
	 * We want to find the place to start looking. so we do a binary search for
	 * the "fallback" nameless entry. If we find it, we advance past it and record
	 * the index.
	 */
	error = git_vector_bsearch(&idx, (git_vector *)&mm->entries, &needle);
	if (error >= 0)
		fallback = idx++;
	else if (error != GIT_ENOTFOUND)
		return NULL;

	/* do a linear search for an exact match */
	for (; idx < git_vector_length(&mm->entries); ++idx) {
		entry = git_vector_get(&mm->entries, idx);

		if (git__strcmp(entry->replace_email, email))
			break; /* it's a different email, so we're done looking */

		assert(entry->replace_name); /* should be specific */
		if (!name || !git__strcmp(entry->replace_name, name))
			return entry;
	}

	if (fallback < 0)
		return NULL; /* no fallback */
	return git_vector_get(&mm->entries, fallback);
}

int git_mailmap_resolve(
	const char **real_name, const char **real_email,
	const git_mailmap *mailmap,
	const char *name, const char *email)
{
	const git_mailmap_entry *entry = NULL;
	assert(name && email);

	*real_name = name;
	*real_email = email;

	if ((entry = git_mailmap_entry_lookup(mailmap, name, email))) {
		if (entry->real_name)
			*real_name = entry->real_name;
		if (entry->real_email)
			*real_email = entry->real_email;
	}
	return 0;
}

int git_mailmap_resolve_signature(
	git_signature **out, const git_mailmap *mailmap, const git_signature *sig)
{
	const char *name = NULL;
	const char *email = NULL;
	int error;

	if (!sig)
		return 0;

	error = git_mailmap_resolve(&name, &email, mailmap, sig->name, sig->email);
	if (error < 0)
		return error;

	error = git_signature_new(out, name, email, sig->when.time, sig->when.offset);
	if (error < 0)
		return error;

	/* Copy over the sign, as git_signature_new doesn't let you pass it. */
	(*out)->when.sign = sig->when.sign;
	return 0;
}
