/*
 * Another stupid program, this one parsing the headers of an
 * email to figure out authorship and subject
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iconv.h>
#include "git-compat-util.h"
#include "cache.h"

static FILE *cmitmsg, *patchfile;

static int keep_subject = 0;
static char *metainfo_charset = NULL;
static char line[1000];
static char date[1000];
static char name[1000];
static char email[1000];
static char subject[1000];

static enum  {
	TE_DONTCARE, TE_QP, TE_BASE64,
} transfer_encoding;
static char charset[256];

static char multipart_boundary[1000];
static int multipart_boundary_len;
static int patch_lines = 0;

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 handle_from(char *line)
{
	char *at = strchr(line, '@');
	char *dst;

	if (!at)
		return 0;

	/*
	 * 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_date(char *line)
{
	strcpy(date, line);
	return 0;
}

static int handle_subject(char *line)
{
	strcpy(subject, line);
	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)
{
	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;
}

static int handle_subcontent_type(char *line)
{
	/* We do not want to mess with boundary.  Note that we do not
	 * handle nested multipart.
	 */
	if (strcasestr(line, "boundary=")) {
		fprintf(stderr, "Not handling nested multipart message.\n");
		exit(1);
	}
	slurp_attr(line, "charset=", charset);
	if (*charset) {
		int i, c;
		for (i = 0; (c = charset[i]) != 0; i++)
			charset[i] = tolower(c);
	}
	return 0;
}

static int handle_content_type(char *line)
{
	*multipart_boundary = 0;
	if (slurp_attr(line, "boundary=", multipart_boundary + 2)) {
		memcpy(multipart_boundary, "--", 2);
		multipart_boundary_len = strlen(multipart_boundary);
	}
	slurp_attr(line, "charset=", charset);
	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, multipart_boundary, multipart_boundary_len));
}

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

#define SEEN_FROM 01
#define SEEN_DATE 02
#define SEEN_SUBJECT 04

/* First lines of body can have From:, Date:, and Subject: */
static int handle_inbody_header(int *seen, char *line)
{
	if (!memcmp("From:", line, 5) && isspace(line[5])) {
		if (!(*seen & SEEN_FROM) && handle_from(line+6)) {
			*seen |= SEEN_FROM;
			return 1;
		}
	}
	if (!memcmp("Date:", line, 5) && isspace(line[5])) {
		if (!(*seen & SEEN_DATE)) {
			handle_date(line+6);
			*seen |= SEEN_DATE;
			return 1;
		}
	}
	if (!memcmp("Subject:", line, 8) && isspace(line[8])) {
		if (!(*seen & SEEN_SUBJECT)) {
			handle_subject(line+9);
			*seen |= SEEN_SUBJECT;
			return 1;
		}
	}
	if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
		if (!(*seen & SEEN_SUBJECT)) {
			handle_subject(line);
			*seen |= SEEN_SUBJECT;
			return 1;
		}
	}
	return 0;
}

static char *cleanup_subject(char *subject)
{
	if (keep_subject)
		return 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;
		}
		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;
			}
		}
	}
}

typedef int (*header_fn_t)(char *);
struct header_def {
	const char *name;
	header_fn_t func;
	int namelen;
};

static void check_header(char *line, int len, struct header_def *header)
{
	int i;

	if (header[0].namelen <= 0) {
		for (i = 0; header[i].name; i++)
			header[i].namelen = strlen(header[i].name);
	}
	for (i = 0; header[i].name; i++) {
		int len = header[i].namelen;
		if (!strncasecmp(line, header[i].name, len) &&
		    line[len] == ':' && isspace(line[len + 1])) {
			header[i].func(line + len + 2);
			break;
		}
	}
}

static void check_subheader_line(char *line, int len)
{
	static struct header_def header[] = {
		{ "Content-Type", handle_subcontent_type },
		{ "Content-Transfer-Encoding",
		  handle_content_transfer_encoding },
		{ NULL },
	};
	check_header(line, len, header);
}
static void check_header_line(char *line, int len)
{
	static struct header_def header[] = {
		{ "From", handle_from },
		{ "Date", handle_date },
		{ "Subject", handle_subject },
		{ "Content-Type", handle_content_type },
		{ "Content-Transfer-Encoding",
		  handle_content_transfer_encoding },
		{ NULL },
	};
	check_header(line, len, header);
}

static int read_one_header_line(char *line, int sz, FILE *in)
{
	int ofs = 0;
	while (ofs < sz) {
		int peek, len;
		if (fgets(line + ofs, sz - ofs, in) == NULL)
			return ofs;
		len = eatspace(line + ofs);
		if (len == 0)
			return ofs;
		peek = fgetc(in); ungetc(peek, in);
		if (peek == ' ' || peek == '\t') {
			/* Yuck, 2822 header "folding" */
			ofs += len;
			continue;
		}
		return ofs + len;
	}
	return ofs;
}

static unsigned hexval(int c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return ~0;
}

static int decode_q_segment(char *in, char *ot, char *ep)
{
	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++));
		}
		else
			*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;
}

static void convert_to_utf8(char *line, char *charset)
{
	char *in, *out;
	size_t insize, outsize, nrc;
	char outbuf[4096]; /* cheat */
	static char latin_one[] = "latin-1";
	char *input_charset = *charset ? charset : latin_one;
	iconv_t conv = iconv_open(metainfo_charset, input_charset);

	if (conv == (iconv_t) -1) {
		static int warned_latin1_once = 0;
		if (input_charset != latin_one) {
			fprintf(stderr, "cannot convert from %s to %s\n",
				input_charset, metainfo_charset);
			*charset = 0;
		}
		else if (!warned_latin1_once) {
			warned_latin1_once = 1;
			fprintf(stderr, "tried to convert from %s to %s, "
				"but your iconv does not work with it.\n",
				input_charset, metainfo_charset);
		}
		return;
	}
	in = line;
	insize = strlen(in);
	out = outbuf;
	outsize = sizeof(outbuf);
	nrc = iconv(conv, &in, &insize, &out, &outsize);
	iconv_close(conv);
	if (nrc == (size_t) -1)
		return;
	*out = 0;
	strcpy(line, outbuf);
}

static void decode_header_bq(char *it)
{
	char *in, *out, *ep, *cp, *sp;
	char outbuf[1000];

	in = it;
	out = outbuf;
	while ((ep = strstr(in, "=?")) != NULL) {
		int sz, encoding;
		char charset_q[256], piecebuf[256];
		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; /* 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; /* no munging */
		ep = strstr(cp + 3, "?=");
		if (!ep)
			return; /* no munging */
		switch (tolower(encoding)) {
		default:
			return; /* no munging */
		case 'b':
			sz = decode_b_segment(cp + 3, piecebuf, ep);
			break;
		case 'q':
			sz = decode_q_segment(cp + 3, piecebuf, ep);
			break;
		}
		if (sz < 0)
			return;
		if (metainfo_charset)
			convert_to_utf8(piecebuf, charset_q);
		strcpy(out, piecebuf);
		out += strlen(out);
		in = ep + 2;
	}
	strcpy(out, in);
	strcpy(it, outbuf);
}

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);
		break;
	case TE_BASE64:
		ep = line + strlen(line);
		decode_b_segment(line, line, ep);
		break;
	case TE_DONTCARE:
		break;
	}
}

static void handle_info(void)
{
	char *sub;
	static int done_info = 0;

	if (done_info)
		return;

	done_info = 1;
	sub = cleanup_subject(subject);
	cleanup_space(name);
	cleanup_space(date);
	cleanup_space(email);
	cleanup_space(sub);

	/* Unwrap inline B and Q encoding, and optionally
	 * normalize the meta information to utf8.
	 */
	decode_header_bq(name);
	decode_header_bq(date);
	decode_header_bq(email);
	decode_header_bq(sub);
	printf("Author: %s\nEmail: %s\nSubject: %s\nDate: %s\n\n",
	       name, email, sub, date);
}

/* We are inside message body and have read line[] already.
 * Spit out the commit log.
 */
static int handle_commit_msg(void)
{
	if (!cmitmsg)
		return 0;
	do {
		if (!memcmp("diff -", line, 6) ||
		    !memcmp("---", line, 3) ||
		    !memcmp("Index: ", line, 7))
			break;
		if ((multipart_boundary[0] && is_multipart_boundary(line))) {
			/* We come here when the first part had only
			 * the commit message without any patch.  We
			 * pretend we have not seen this line yet, and
			 * go back to the loop.
			 */
			return 1;
		}

		/* Unwrap transfer encoding and optionally
		 * normalize the log message to UTF-8.
		 */
		decode_transfer_encoding(line);
		if (metainfo_charset)
			convert_to_utf8(line, charset);
		fputs(line, cmitmsg);
	} while (fgets(line, sizeof(line), stdin) != NULL);
	fclose(cmitmsg);
	cmitmsg = NULL;
	return 0;
}

/* We have done the commit message and have the first
 * line of the patch in line[].
 */
static void handle_patch(void)
{
	do {
		if (multipart_boundary[0] && is_multipart_boundary(line))
			break;
		/* Only unwrap transfer encoding but otherwise do not
		 * do anything.  We do *NOT* want UTF-8 conversion
		 * here; we are dealing with the user payload.
		 */
		decode_transfer_encoding(line);
		fputs(line, patchfile);
		patch_lines++;
	} while (fgets(line, sizeof(line), stdin) != NULL);
}

/* multipart boundary and transfer encoding are set up for us, and we
 * are at the end of the sub header.  do equivalent of handle_body up
 * to the next boundary without closing patchfile --- we will expect
 * that the first part to contain commit message and a patch, and
 * handle other parts as pure patches.
 */
static int handle_multipart_one_part(void)
{
	int seen = 0;
	int n = 0;
	int len;

	while (fgets(line, sizeof(line), stdin) != NULL) {
	again:
		len = eatspace(line);
		n++;
		if (!len)
			continue;
		if (is_multipart_boundary(line))
			break;
		if (0 <= seen && handle_inbody_header(&seen, line))
			continue;
		seen = -1; /* no more inbody headers */
		line[len] = '\n';
		handle_info();
		if (handle_commit_msg())
			goto again;
		handle_patch();
		break;
	}
	if (n == 0)
		return -1;
	return 0;
}

static void handle_multipart_body(void)
{
	int part_num = 0;

	/* Skip up to the first boundary */
	while (fgets(line, sizeof(line), stdin) != NULL)
		if (is_multipart_boundary(line)) {
			part_num = 1;
			break;
		}
	if (!part_num)
		return;
	/* We are on boundary line.  Start slurping the subhead. */
	while (1) {
		int len = read_one_header_line(line, sizeof(line), stdin);
		if (!len) {
			if (handle_multipart_one_part() < 0)
				return;
		}
		else
			check_subheader_line(line, len);
	}
	fclose(patchfile);
	if (!patch_lines) {
		fprintf(stderr, "No patch found\n");
		exit(1);
	}
}

/* Non multipart message */
static void handle_body(void)
{
	int seen = 0;

	while (fgets(line, sizeof(line), stdin) != NULL) {
		int len = eatspace(line);
		if (!len)
			continue;
		if (0 <= seen && handle_inbody_header(&seen, line))
			continue;
		seen = -1; /* no more inbody headers */
		line[len] = '\n';
		handle_info();
		handle_commit_msg();
		handle_patch();
		break;
	}
	fclose(patchfile);
	if (!patch_lines) {
		fprintf(stderr, "No patch found\n");
		exit(1);
	}
}

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

int main(int argc, char **argv)
{
	/* NEEDSWORK: might want to do the optional .git/ directory
	 * discovery
	 */
	git_config(git_default_config);

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

	if (argc != 3)
		usage(mailinfo_usage);
	cmitmsg = fopen(argv[1], "w");
	if (!cmitmsg) {
		perror(argv[1]);
		exit(1);
	}
	patchfile = fopen(argv[2], "w");
	if (!patchfile) {
		perror(argv[2]);
		exit(1);
	}
	while (1) {
		int len = read_one_header_line(line, sizeof(line), stdin);
		if (!len) {
			if (multipart_boundary[0])
				handle_multipart_body();
			else
				handle_body();
			break;
		}
		check_header_line(line, len);
	}
	return 0;
}
