/*
 * Another stupid program, this one parsing the headers of an
 * email to figure out authorship and subject
 */
#include "cache.h"
#include "builtin.h"
#include "utf8.h"

static FILE *cmitmsg, *patchfile, *fin, *fout;

static int keep_subject;
static const char *metainfo_charset;
static char line[1000];
static char name[1000];
static char email[1000];

static enum  {
	TE_DONTCARE, TE_QP, TE_BASE64,
} transfer_encoding;
static enum  {
	TYPE_TEXT, TYPE_OTHER,
} message_type;

static char charset[256];
static int patch_lines;
static char **p_hdr_data, **s_hdr_data;

#define MAX_HDR_PARSED 10
#define MAX_BOUNDARIES 5

static char *sanity_check(char *name, char *email)
{
	int len = strlen(name);
	if (len < 3 || len > 60)
		return email;
	if (strchr(name, '@') || strchr(name, '<') || strchr(name, '>'))
		return email;
	return name;
}

static int bogus_from(char *line)
{
	/* John Doe <johndoe> */
	char *bra, *ket, *dst, *cp;

	/* This is fallback, so do not bother if we already have an
	 * e-mail address.
	 */
	if (*email)
		return 0;

	bra = strchr(line, '<');
	if (!bra)
		return 0;
	ket = strchr(bra, '>');
	if (!ket)
		return 0;

	for (dst = email, cp = bra+1; cp < ket; )
		*dst++ = *cp++;
	*dst = 0;
	for (cp = line; isspace(*cp); cp++)
		;
	for (bra--; isspace(*bra); bra--)
		*bra = 0;
	cp = sanity_check(cp, email);
	strcpy(name, cp);
	return 1;
}

static int handle_from(char *in_line)
{
	char line[1000];
	char *at;
	char *dst;

	strcpy(line, in_line);
	at = strchr(line, '@');
	if (!at)
		return bogus_from(line);

	/*
	 * If we already have one email, don't take any confusing lines
	 */
	if (*email && strchr(at+1, '@'))
		return 0;

	/* Pick up the string around '@', possibly delimited with <>
	 * pair; that is the email part.  White them out while copying.
	 */
	while (at > line) {
		char c = at[-1];
		if (isspace(c))
			break;
		if (c == '<') {
			at[-1] = ' ';
			break;
		}
		at--;
	}
	dst = email;
	for (;;) {
		unsigned char c = *at;
		if (!c || c == '>' || isspace(c)) {
			if (c == '>')
				*at = ' ';
			break;
		}
		*at++ = ' ';
		*dst++ = c;
	}
	*dst++ = 0;

	/* The remainder is name.  It could be "John Doe <john.doe@xz>"
	 * or "john.doe@xz (John Doe)", but we have whited out the
	 * email part, so trim from both ends, possibly removing
	 * the () pair at the end.
	 */
	at = line + strlen(line);
	while (at > line) {
		unsigned char c = *--at;
		if (!isspace(c)) {
			at[(c == ')') ? 0 : 1] = 0;
			break;
		}
	}

	at = line;
	for (;;) {
		unsigned char c = *at;
		if (!c || !isspace(c)) {
			if (c == '(')
				at++;
			break;
		}
		at++;
	}
	at = sanity_check(at, email);
	strcpy(name, at);
	return 1;
}

static int handle_header(char *line, char *data, int ofs)
{
	if (!line || !data)
		return 1;

	strcpy(data, line+ofs);

	return 0;
}

/* NOTE NOTE NOTE.  We do not claim we do full MIME.  We just attempt
 * to have enough heuristics to grok MIME encoded patches often found
 * on our mailing lists.  For example, we do not even treat header lines
 * case insensitively.
 */

static int slurp_attr(const char *line, const char *name, char *attr)
{
	const char *ends, *ap = strcasestr(line, name);
	size_t sz;

	if (!ap) {
		*attr = 0;
		return 0;
	}
	ap += strlen(name);
	if (*ap == '"') {
		ap++;
		ends = "\"";
	}
	else
		ends = "; \t";
	sz = strcspn(ap, ends);
	memcpy(attr, ap, sz);
	attr[sz] = 0;
	return 1;
}

struct content_type {
	char *boundary;
	int boundary_len;
};

static struct content_type content[MAX_BOUNDARIES];

static struct content_type *content_top = content;

static int handle_content_type(char *line)
{
	char boundary[256];

	if (strcasestr(line, "text/") == NULL)
		 message_type = TYPE_OTHER;
	if (slurp_attr(line, "boundary=", boundary + 2)) {
		memcpy(boundary, "--", 2);
		if (content_top++ >= &content[MAX_BOUNDARIES]) {
			fprintf(stderr, "Too many boundaries to handle\n");
			exit(1);
		}
		content_top->boundary_len = strlen(boundary);
		content_top->boundary = xmalloc(content_top->boundary_len+1);
		strcpy(content_top->boundary, boundary);
	}
	if (slurp_attr(line, "charset=", charset)) {
		int i, c;
		for (i = 0; (c = charset[i]) != 0; i++)
			charset[i] = tolower(c);
	}
	return 0;
}

static int handle_content_transfer_encoding(char *line)
{
	if (strcasestr(line, "base64"))
		transfer_encoding = TE_BASE64;
	else if (strcasestr(line, "quoted-printable"))
		transfer_encoding = TE_QP;
	else
		transfer_encoding = TE_DONTCARE;
	return 0;
}

static int is_multipart_boundary(const char *line)
{
	return (!memcmp(line, content_top->boundary, content_top->boundary_len));
}

static int eatspace(char *line)
{
	int len = strlen(line);
	while (len > 0 && isspace(line[len-1]))
		line[--len] = 0;
	return len;
}

static char *cleanup_subject(char *subject)
{
	for (;;) {
		char *p;
		int len, remove;
		switch (*subject) {
		case 'r': case 'R':
			if (!memcmp("e:", subject+1, 2)) {
				subject += 3;
				continue;
			}
			break;
		case ' ': case '\t': case ':':
			subject++;
			continue;

		case '[':
			p = strchr(subject, ']');
			if (!p) {
				subject++;
				continue;
			}
			len = strlen(p);
			remove = p - subject;
			if (remove <= len *2) {
				subject = p+1;
				continue;
			}
			break;
		}
		eatspace(subject);
		return subject;
	}
}

static void cleanup_space(char *buf)
{
	unsigned char c;
	while ((c = *buf) != 0) {
		buf++;
		if (isspace(c)) {
			buf[-1] = ' ';
			c = *buf;
			while (isspace(c)) {
				int len = strlen(buf);
				memmove(buf, buf+1, len);
				c = *buf;
			}
		}
	}
}

static void decode_header(char *it);
static char *header[MAX_HDR_PARSED] = {
	"From","Subject","Date",
};

static int check_header(char *line, char **hdr_data, int overwrite)
{
	int i;

	/* search for the interesting parts */
	for (i = 0; header[i]; i++) {
		int len = strlen(header[i]);
		if ((!hdr_data[i] || overwrite) &&
		    !strncasecmp(line, header[i], len) &&
		    line[len] == ':' && isspace(line[len + 1])) {
			/* Unwrap inline B and Q encoding, and optionally
			 * normalize the meta information to utf8.
			 */
			decode_header(line + len + 2);
			hdr_data[i] = xmalloc(1000 * sizeof(char));
			if (! handle_header(line, hdr_data[i], len + 2)) {
				return 1;
			}
		}
	}

	/* Content stuff */
	if (!strncasecmp(line, "Content-Type", 12) &&
		line[12] == ':' && isspace(line[12 + 1])) {
		decode_header(line + 12 + 2);
		if (! handle_content_type(line)) {
			return 1;
		}
	}
	if (!strncasecmp(line, "Content-Transfer-Encoding", 25) &&
		line[25] == ':' && isspace(line[25 + 1])) {
		decode_header(line + 25 + 2);
		if (! handle_content_transfer_encoding(line)) {
			return 1;
		}
	}

	/* for inbody stuff */
	if (!memcmp(">From", line, 5) && isspace(line[5]))
		return 1;
	if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
		for (i = 0; header[i]; i++) {
			if (!memcmp("Subject: ", header[i], 9)) {
				if (! handle_header(line, hdr_data[i], 0)) {
					return 1;
				}
			}
		}
	}

	/* no match */
	return 0;
}

static int is_rfc2822_header(char *line)
{
	/*
	 * The section that defines the loosest possible
	 * field name is "3.6.8 Optional fields".
	 *
	 * optional-field = field-name ":" unstructured CRLF
	 * field-name = 1*ftext
	 * ftext = %d33-57 / %59-126
	 */
	int ch;
	char *cp = line;

	/* Count mbox From headers as headers */
	if (!memcmp(line, "From ", 5) || !memcmp(line, ">From ", 6))
		return 1;

	while ((ch = *cp++)) {
		if (ch == ':')
			return cp != line;
		if ((33 <= ch && ch <= 57) ||
		    (59 <= ch && ch <= 126))
			continue;
		break;
	}
	return 0;
}

/*
 * sz is size of 'line' buffer in bytes.  Must be reasonably
 * long enough to hold one physical real-world e-mail line.
 */
static int read_one_header_line(char *line, int sz, FILE *in)
{
	int len;

	/*
	 * We will read at most (sz-1) bytes and then potentially
	 * re-add NUL after it.  Accessing line[sz] after this is safe
	 * and we can allow len to grow up to and including sz.
	 */
	sz--;

	/* Get the first part of the line. */
	if (!fgets(line, sz, in))
		return 0;

	/*
	 * Is it an empty line or not a valid rfc2822 header?
	 * If so, stop here, and return false ("not a header")
	 */
	len = eatspace(line);
	if (!len || !is_rfc2822_header(line)) {
		/* Re-add the newline */
		line[len] = '\n';
		line[len + 1] = '\0';
		return 0;
	}

	/*
	 * Now we need to eat all the continuation lines..
	 * Yuck, 2822 header "folding"
	 */
	for (;;) {
		int peek, addlen;
		static char continuation[1000];

		peek = fgetc(in); ungetc(peek, in);
		if (peek != ' ' && peek != '\t')
			break;
		if (!fgets(continuation, sizeof(continuation), in))
			break;
		addlen = eatspace(continuation);
		if (len < sz - 1) {
			if (addlen >= sz - len)
				addlen = sz - len - 1;
			memcpy(line + len, continuation, addlen);
			line[len] = '\n';
			len += addlen;
		}
	}
	line[len] = 0;

	return 1;
}

static int decode_q_segment(char *in, char *ot, char *ep, int rfc2047)
{
	int c;
	while ((c = *in++) != 0 && (in <= ep)) {
		if (c == '=') {
			int d = *in++;
			if (d == '\n' || !d)
				break; /* drop trailing newline */
			*ot++ = ((hexval(d) << 4) | hexval(*in++));
			continue;
		}
		if (rfc2047 && c == '_') /* rfc2047 4.2 (2) */
			c = 0x20;
		*ot++ = c;
	}
	*ot = 0;
	return 0;
}

static int decode_b_segment(char *in, char *ot, char *ep)
{
	/* Decode in..ep, possibly in-place to ot */
	int c, pos = 0, acc = 0;

	while ((c = *in++) != 0 && (in <= ep)) {
		if (c == '+')
			c = 62;
		else if (c == '/')
			c = 63;
		else if ('A' <= c && c <= 'Z')
			c -= 'A';
		else if ('a' <= c && c <= 'z')
			c -= 'a' - 26;
		else if ('0' <= c && c <= '9')
			c -= '0' - 52;
		else if (c == '=') {
			/* padding is almost like (c == 0), except we do
			 * not output NUL resulting only from it;
			 * for now we just trust the data.
			 */
			c = 0;
		}
		else
			continue; /* garbage */
		switch (pos++) {
		case 0:
			acc = (c << 2);
			break;
		case 1:
			*ot++ = (acc | (c >> 4));
			acc = (c & 15) << 4;
			break;
		case 2:
			*ot++ = (acc | (c >> 2));
			acc = (c & 3) << 6;
			break;
		case 3:
			*ot++ = (acc | c);
			acc = pos = 0;
			break;
		}
	}
	*ot = 0;
	return 0;
}

/*
 * When there is no known charset, guess.
 *
 * Right now we assume that if the target is UTF-8 (the default),
 * and it already looks like UTF-8 (which includes US-ASCII as its
 * subset, of course) then that is what it is and there is nothing
 * to do.
 *
 * Otherwise, we default to assuming it is Latin1 for historical
 * reasons.
 */
static const char *guess_charset(const char *line, const char *target_charset)
{
	if (is_encoding_utf8(target_charset)) {
		if (is_utf8(line))
			return NULL;
	}
	return "latin1";
}

static void convert_to_utf8(char *line, const char *charset)
{
	char *out;

	if (!charset || !*charset) {
		charset = guess_charset(line, metainfo_charset);
		if (!charset)
			return;
	}

	if (!strcmp(metainfo_charset, charset))
		return;
	out = reencode_string(line, metainfo_charset, charset);
	if (!out)
		die("cannot convert from %s to %s\n",
		    charset, metainfo_charset);
	strcpy(line, out);
	free(out);
}

static int decode_header_bq(char *it)
{
	char *in, *out, *ep, *cp, *sp;
	char outbuf[1000];
	int rfc2047 = 0;

	in = it;
	out = outbuf;
	while ((ep = strstr(in, "=?")) != NULL) {
		int sz, encoding;
		char charset_q[256], piecebuf[256];
		rfc2047 = 1;

		if (in != ep) {
			sz = ep - in;
			memcpy(out, in, sz);
			out += sz;
			in += sz;
		}
		/* E.g.
		 * ep : "=?iso-2022-jp?B?GyR...?= foo"
		 * ep : "=?ISO-8859-1?Q?Foo=FCbar?= baz"
		 */
		ep += 2;
		cp = strchr(ep, '?');
		if (!cp)
			return rfc2047; /* no munging */
		for (sp = ep; sp < cp; sp++)
			charset_q[sp - ep] = tolower(*sp);
		charset_q[cp - ep] = 0;
		encoding = cp[1];
		if (!encoding || cp[2] != '?')
			return rfc2047; /* no munging */
		ep = strstr(cp + 3, "?=");
		if (!ep)
			return rfc2047; /* no munging */
		switch (tolower(encoding)) {
		default:
			return rfc2047; /* no munging */
		case 'b':
			sz = decode_b_segment(cp + 3, piecebuf, ep);
			break;
		case 'q':
			sz = decode_q_segment(cp + 3, piecebuf, ep, 1);
			break;
		}
		if (sz < 0)
			return rfc2047;
		if (metainfo_charset)
			convert_to_utf8(piecebuf, charset_q);
		strcpy(out, piecebuf);
		out += strlen(out);
		in = ep + 2;
	}
	strcpy(out, in);
	strcpy(it, outbuf);
	return rfc2047;
}

static void decode_header(char *it)
{

	if (decode_header_bq(it))
		return;
	/* otherwise "it" is a straight copy of the input.
	 * This can be binary guck but there is no charset specified.
	 */
	if (metainfo_charset)
		convert_to_utf8(it, "");
}

static void decode_transfer_encoding(char *line)
{
	char *ep;

	switch (transfer_encoding) {
	case TE_QP:
		ep = line + strlen(line);
		decode_q_segment(line, line, ep, 0);
		break;
	case TE_BASE64:
		ep = line + strlen(line);
		decode_b_segment(line, line, ep);
		break;
	case TE_DONTCARE:
		break;
	}
}

static int handle_filter(char *line);

static int find_boundary(void)
{
	while(fgets(line, sizeof(line), fin) != NULL) {
		if (is_multipart_boundary(line))
			return 1;
	}
	return 0;
}

static int handle_boundary(void)
{
	char newline[]="\n";
again:
	if (!memcmp(line+content_top->boundary_len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		free(content_top->boundary);

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (content_top-- < content) {
			fprintf(stderr, "Detected mismatched boundaries, "
					"can't recover\n");
			exit(1);
		}
		handle_filter(newline);

		/* skip to the next boundary */
		if (!find_boundary())
			return 0;
		goto again;
	}

	/* set some defaults */
	transfer_encoding = TE_DONTCARE;
	charset[0] = 0;
	message_type = TYPE_TEXT;

	/* slurp in this section's info */
	while (read_one_header_line(line, sizeof(line), fin))
		check_header(line, p_hdr_data, 0);

	/* eat the blank line after section info */
	return (fgets(line, sizeof(line), fin) != NULL);
}

static inline int patchbreak(const char *line)
{
	/* Beginning of a "diff -" header? */
	if (!memcmp("diff -", line, 6))
		return 1;

	/* CVS "Index: " line? */
	if (!memcmp("Index: ", line, 7))
		return 1;

	/*
	 * "--- <filename>" starts patches without headers
	 * "---<sp>*" is a manual separator
	 */
	if (!memcmp("---", line, 3)) {
		line += 3;
		/* space followed by a filename? */
		if (line[0] == ' ' && !isspace(line[1]))
			return 1;
		/* Just whitespace? */
		for (;;) {
			unsigned char c = *line++;
			if (c == '\n')
				return 1;
			if (!isspace(c))
				break;
		}
		return 0;
	}
	return 0;
}


static int handle_commit_msg(char *line)
{
	static int still_looking = 1;

	if (!cmitmsg)
		return 0;

	if (still_looking) {
		char *cp = line;
		if (isspace(*line)) {
			for (cp = line + 1; *cp; cp++) {
				if (!isspace(*cp))
					break;
			}
			if (!*cp)
				return 0;
		}
		if ((still_looking = check_header(cp, s_hdr_data, 0)) != 0)
			return 0;
	}

	/* normalize the log message to UTF-8. */
	if (metainfo_charset)
		convert_to_utf8(line, charset);

	if (patchbreak(line)) {
		fclose(cmitmsg);
		cmitmsg = NULL;
		return 1;
	}

	fputs(line, cmitmsg);
	return 0;
}

static int handle_patch(char *line)
{
	fputs(line, patchfile);
	patch_lines++;
	return 0;
}

static int handle_filter(char *line)
{
	static int filter = 0;

	/* filter tells us which part we left off on
	 * a non-zero return indicates we hit a filter point
	 */
	switch (filter) {
	case 0:
		if (!handle_commit_msg(line))
			break;
		filter++;
	case 1:
		if (!handle_patch(line))
			break;
		filter++;
	default:
		return 1;
	}

	return 0;
}

static void handle_body(void)
{
	int rc = 0;
	static char newline[2000];
	static char *np = newline;

	/* Skip up to the first boundary */
	if (content_top->boundary) {
		if (!find_boundary())
			return;
	}

	do {
		/* process any boundary lines */
		if (content_top->boundary && is_multipart_boundary(line)) {
			/* flush any leftover */
			if ((transfer_encoding == TE_BASE64)  &&
			    (np != newline)) {
				handle_filter(newline);
			}
			if (!handle_boundary())
				return;
		}

		/* Unwrap transfer encoding */
		decode_transfer_encoding(line);

		switch (transfer_encoding) {
		case TE_BASE64:
		{
			char *op = line;

			/* binary data most likely doesn't have newlines */
			if (message_type != TYPE_TEXT) {
				rc = handle_filter(line);
				break;
			}

			/* this is a decoded line that may contain
			 * multiple new lines.  Pass only one chunk
			 * at a time to handle_filter()
			 */

			do {
				while (*op != '\n' && *op != 0)
					*np++ = *op++;
				*np = *op;
				if (*np != 0) {
					/* should be sitting on a new line */
					*(++np) = 0;
					op++;
					rc = handle_filter(newline);
					np = newline;
				}
			} while (*op != 0);
			/* the partial chunk is saved in newline and
			 * will be appended by the next iteration of fgets
			 */
			break;
		}
		default:
			rc = handle_filter(line);
		}
		if (rc)
			/* nothing left to filter */
			break;
	} while (fgets(line, sizeof(line), fin));

	return;
}

static void output_header_lines(FILE *fout, const char *hdr, char *data)
{
	while (1) {
		char *ep = strchr(data, '\n');
		int len;
		if (!ep)
			len = strlen(data);
		else
			len = ep - data;
		fprintf(fout, "%s: %.*s\n", hdr, len, data);
		if (!ep)
			break;
		data = ep + 1;
	}
}

static void handle_info(void)
{
	char *sub;
	char *hdr;
	int i;

	for (i = 0; header[i]; i++) {

		/* only print inbody headers if we output a patch file */
		if (patch_lines && s_hdr_data[i])
			hdr = s_hdr_data[i];
		else if (p_hdr_data[i])
			hdr = p_hdr_data[i];
		else
			continue;

		if (!memcmp(header[i], "Subject", 7)) {
			if (keep_subject)
				sub = hdr;
			else {
				sub = cleanup_subject(hdr);
				cleanup_space(sub);
			}
			output_header_lines(fout, "Subject", sub);
		} else if (!memcmp(header[i], "From", 4)) {
			handle_from(hdr);
			fprintf(fout, "Author: %s\n", name);
			fprintf(fout, "Email: %s\n", email);
		} else {
			cleanup_space(hdr);
			fprintf(fout, "%s: %s\n", header[i], hdr);
		}
	}
	fprintf(fout, "\n");
}

static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
		    const char *msg, const char *patch)
{
	keep_subject = ks;
	metainfo_charset = encoding;
	fin = in;
	fout = out;

	cmitmsg = fopen(msg, "w");
	if (!cmitmsg) {
		perror(msg);
		return -1;
	}
	patchfile = fopen(patch, "w");
	if (!patchfile) {
		perror(patch);
		fclose(cmitmsg);
		return -1;
	}

	p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));
	s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));

	/* process the email header */
	while (read_one_header_line(line, sizeof(line), fin))
		check_header(line, p_hdr_data, 1);

	handle_body();
	handle_info();

	return 0;
}

static const char mailinfo_usage[] =
	"git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";

int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{
	const char *def_charset;

	/* NEEDSWORK: might want to do the optional .git/ directory
	 * discovery
	 */
	git_config(git_default_config);

	def_charset = (git_commit_encoding ? git_commit_encoding : "utf-8");
	metainfo_charset = def_charset;

	while (1 < argc && argv[1][0] == '-') {
		if (!strcmp(argv[1], "-k"))
			keep_subject = 1;
		else if (!strcmp(argv[1], "-u"))
			metainfo_charset = def_charset;
		else if (!strcmp(argv[1], "-n"))
			metainfo_charset = NULL;
		else if (!prefixcmp(argv[1], "--encoding="))
			metainfo_charset = argv[1] + 11;
		else
			usage(mailinfo_usage);
		argc--; argv++;
	}

	if (argc != 3)
		usage(mailinfo_usage);

	return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]);
}
