/*
 * Locking here is not quite right.
 * Calling qlock(&z->lk) can block the proc,
 * and when it comes back, boxes and msgs might have been freed
 * (if the refresh proc was holding the lock and in the middle of a
 * redial).  I've tried to be careful about not assuming boxes continue
 * to exist across imap commands, but maybe this isn't really tenable.
 * Maybe instead we should ref count the boxes and messages.
 */

#include "a.h"
#include <libsec.h>

struct Imap
{
	int		connected;
	int		autoreconnect;
	int		ticks;	/* until boom! */
	char*	server;
	char*	root;
	int		mode;
	int		fd;
	Biobuf	b;
	Ioproc*	io;
	QLock	lk;
	QLock	rlk;
	Rendez	r;

	Box*		inbox;
	Box*		box;
	Box*		nextbox;

	/* SEARCH results */
	uint		*uid;
	uint		nuid;
};

static struct {
	char *name;
	int flag;
} flagstab[] = 
{
	"Junk",	FlagJunk,
	"NonJunk",	FlagNonJunk,
	"\\Answered",	FlagReplied,
	"\\Flagged",	FlagFlagged,
	"\\Deleted",	FlagDeleted,
	"\\Draft",		FlagDraft,
	"\\Recent",	FlagRecent,
	"\\Seen",		FlagSeen,
	"\\NoInferiors",	FlagNoInferiors,
	"\\NoSelect",	FlagNoSelect,
	"\\Marked",	FlagMarked,
	"\\UnMarked",	FlagUnMarked
};

int			chattyimap;

static char	*tag = "#";

static void	checkbox(Imap*, Box*);
static char*	copyaddrs(Sx*);
static void	freeup(UserPasswd*);
static int		getbox(Imap*, Box*);
static int		getboxes(Imap*);
static char*	gsub(char*, char*, char*);
static int		imapcmd(Imap*, Box*, char*, ...);
static Sx*		imapcmdsx(Imap*, Box*, char*, ...);
static Sx*		imapcmdsx0(Imap*, char*, ...);
static Sx*		imapvcmdsx(Imap*, Box*, char*, va_list);
static Sx*		imapvcmdsx0(Imap*, char*, va_list);
static int		imapdial(char*, int);
static int		imaplogin(Imap*);
static int		imapquote(Fmt*);
static int		imapreconnect(Imap*);
static void	imaprefreshthread(void*);
static void	imaptimerproc(void*);
static Sx*		imapwaitsx(Imap*);
static int		isatom(Sx *v, char *name);
static int		islist(Sx *v);
static int		isnil(Sx *v);
static int		isnumber(Sx *sx);
static int		isstring(Sx *sx);
static int		ioimapdial(Ioproc*, char*, int);
static char*	nstring(Sx*);
static void	unexpected(Imap*, Sx*);
static Sx*		zBrdsx(Imap*);

/*
 * Imap connection maintenance and login.
 */

Imap*
imapconnect(char *server, int mode, char *root)
{
	Imap *z;

	fmtinstall('H', encodefmt);
	fmtinstall('Z', imapquote);

	z = emalloc(sizeof *z);
	z->server = estrdup(server);
	z->mode = mode;
	if(root)
		if(root[0] != 0 && root[strlen(root)-1] != '/')
			z->root = smprint("%s/", root);
		else
			z->root = root;
	else
		z->root = "";
	z->fd = -1;
	z->autoreconnect = 0;
	z->io = ioproc();
	
	qlock(&z->lk);
	if(imapreconnect(z) < 0){
		free(z);
		return nil;
	}
	
	z->r.l = &z->rlk;
	z->autoreconnect = 1;
	qunlock(&z->lk);
	
	proccreate(imaptimerproc, z, STACK);
	mailthread(imaprefreshthread, z);
	
	return z;
}

void
imaphangup(Imap *z, int ticks)
{
	z->ticks = ticks;
	if(ticks == 0){
		close(z->fd);
		z->fd = -1;
	}
}

static int
imapreconnect(Imap *z)
{
	Sx *sx;

	z->autoreconnect = 0;
	z->box = nil;
	z->inbox = nil;

	if(z->fd >= 0){
		close(z->fd);
		z->fd = -1;
	}

	if(chattyimap)
		fprint(2, "dial %s...\n", z->server);
	if((z->fd = ioimapdial(z->io, z->server, z->mode)) < 0)
		return -1;
	z->connected = 1;
	Binit(&z->b, z->fd, OREAD);
	if((sx = zBrdsx(z)) == nil){
		werrstr("no greeting");
		goto err;
	}
	if(chattyimap)
		fprint(2, "<I %#$\n", sx);
	if(sx->nsx >= 2 && isatom(sx->sx[0], "*") && isatom(sx->sx[1], "PREAUTH")){
		freesx(sx);
		goto preauth;
	}
	if(!oksx(sx)){
		werrstr("bad greeting - %#$", sx);
		goto err;
	}
	freesx(sx);
	sx = nil;
	if(imaplogin(z) < 0)
		goto err;
preauth:
	if(getboxes(z) < 0 || getbox(z, z->inbox) < 0)
		goto err;
	z->autoreconnect = 1;
	return 0;

err:
	if(z->fd >= 0){
		close(z->fd);
		z->fd = -1;
	}
	if(sx)
		freesx(sx);
	z->autoreconnect = 1;
	z->connected = 0;
	return -1;
}

static int
imaplogin(Imap *z)
{
	Sx *sx;
	UserPasswd *up;

	if((up = auth_getuserpasswd(auth_getkey, "proto=pass role=client service=imap server=%q", z->server)) == nil){
		werrstr("getuserpasswd - %r");
		return -1;
	}

	sx = imapcmdsx(z, nil, "LOGIN %Z %Z", up->user, up->passwd);
	freeup(up);
	if(sx == nil)
		return -1;
	if(!oksx(sx)){
		freesx(sx);
		werrstr("login rejected - %#$", sx);
		return -1;
	}
	return 0;
}

static int
getboxes(Imap *z)
{
	int i;
	Box **r, **w, **e;
	
	for(i=0; i<nboxes; i++){
		boxes[i]->mark = 1;
		boxes[i]->exists = 0;
		boxes[i]->maxseen = 0;
	}
	if(imapcmd(z, nil, "LIST %Z *", z->root) < 0)
		return -1;
	if(z->root != nil && imapcmd(z, nil, "LIST %Z INBOX", "") < 0)
		return -1;
	if(z->nextbox && z->nextbox->mark)
		z->nextbox = nil;
	for(r=boxes, w=boxes, e=boxes+nboxes; r<e; r++){
		if((*r)->mark)
{fprint(2, "*** free box %s %s\n", (*r)->name, (*r)->imapname);
			boxfree(*r);
}
		else
			*w++ = *r;
	}
	nboxes = w - boxes;
	return 0;
}

static int
getbox(Imap *z, Box *b)
{
	int i;
	Msg **r, **w, **e;
	
	if(b == nil)
		return 0;
	
	for(i=0; i<b->nmsg; i++)
		b->msg[i]->imapid = 0;
	if(imapcmd(z, b, "UID FETCH 1:* FLAGS") < 0)
		return -1;
	for(r=b->msg, w=b->msg, e=b->msg+b->nmsg; r<e; r++){
		if((*r)->imapid == 0)
			msgfree(*r);
		else{
			(*r)->ix = w-b->msg;
			*w++ = *r;
		}
	}
	b->nmsg = w - b->msg;
	b->imapinit = 1;
	checkbox(z, b);
	return 0;
}

static void
freeup(UserPasswd *up)
{
	memset(up->user, 0, strlen(up->user));
	memset(up->passwd, 0, strlen(up->passwd));
	free(up);
}

static void
imaptimerproc(void *v)
{
	Imap *z;
	
	z = v;
	for(;;){
		sleep(60*1000);
		qlock(z->r.l);
		rwakeup(&z->r);
		qunlock(z->r.l);
	}
}

static void
checkbox(Imap *z, Box *b)
{
	if(imapcmd(z, b, "NOOP") >= 0){
		if(!b->imapinit)
			getbox(z, b);
		if(!b->imapinit)
			return;
		if(b==z->box && b->exists > b->maxseen){
			imapcmd(z, b, "UID FETCH %d:* FULL",
				b->uidnext);
		}
	}
}

static void
imaprefreshthread(void *v)
{
	Imap *z;
	
	z = v;
	for(;;){
		qlock(z->r.l);
		rsleep(&z->r);
		qunlock(z->r.l);
		
		qlock(&z->lk);
		if(z->inbox)
			checkbox(z, z->inbox);
		qunlock(&z->lk);
	}
}

/*
 * Run a single command and return the Sx.  Does NOT redial.
 */
static Sx*
imapvcmdsx0(Imap *z, char *fmt, va_list arg)
{
	char *s;
	Fmt f;
	int prefix, len;
	Sx *sx;
	
	if(canqlock(&z->lk))
		abort();

	if(z->fd < 0 || !z->connected)
		return nil;

	prefix = strlen(tag)+1;
	fmtstrinit(&f);
	fmtprint(&f, "%s ", tag);
	fmtvprint(&f, fmt, arg);
	fmtprint(&f, "\r\n");
	s = fmtstrflush(&f);
	len = strlen(s);
	s[len-2] = 0;
	if(chattyimap)
		fprint(2, "I> %s\n", s);
	s[len-2] = '\r';
	if(iowrite(z->io, z->fd, s, len) < 0){
		z->connected = 0;
		free(s);
		return nil;
	}
	sx = imapwaitsx(z);
	free(s);
	return sx;
}

static Sx*
imapcmdsx0(Imap *z, char *fmt, ...)
{
	va_list arg;
	Sx *sx;
	
	va_start(arg, fmt);
	sx = imapvcmdsx0(z, fmt, arg);
	va_end(arg);
	return sx;
}

/*
 * Run a single command on box b.  Does redial.
 */
static Sx*
imapvcmdsx(Imap *z, Box *b, char *fmt, va_list arg)
{
	int tries;
	Sx *sx;
	
	tries = 0;
	z->nextbox = b;

	if(z->fd < 0 || !z->connected){
reconnect:
		if(!z->autoreconnect)
			return nil;
		if(imapreconnect(z) < 0)
			return nil;
		if(b && z->nextbox == nil)	/* box disappeared on reconnect */
			return nil;
	}

	if(b && b != z->box){
		if(z->box)
			z->box->imapinit = 0;
		z->box = b;
		if((sx=imapcmdsx0(z, "SELECT %Z", b->imapname)) == nil){
			z->box = nil;
			if(tries++ == 0 && (z->fd < 0 || !z->connected))
				goto reconnect;
			return nil;
		}
		freesx(sx);
	}

	if((sx=imapvcmdsx0(z, fmt, arg)) == nil){
		if(tries++ == 0 && (z->fd < 0 || !z->connected))
			goto reconnect;
		return nil;
	}
	return sx;
}

static int
imapcmd(Imap *z, Box *b, char *fmt, ...)
{
	Sx *sx;
	va_list arg;

	va_start(arg, fmt);
	sx = imapvcmdsx(z, b, fmt, arg);
	va_end(arg);
	if(sx == nil)
		return -1;
	if(sx->nsx < 2 || !isatom(sx->sx[1], "OK")){
		werrstr("%$", sx);
		freesx(sx);
		return -1;
	}
	freesx(sx);
	return 0;
}

static Sx*
imapcmdsx(Imap *z, Box *b, char *fmt, ...)
{
	Sx *sx;
	va_list arg;

	va_start(arg, fmt);
	sx = imapvcmdsx(z, b, fmt, arg);
	va_end(arg);
	return sx;
}

static Sx*
imapwaitsx(Imap *z)
{
	Sx *sx;
	
	while((sx = zBrdsx(z)) != nil){
		if(chattyimap)
			fprint(2, "<| %#$\n", sx);
		if(sx->nsx >= 1 && sx->sx[0]->type == SxAtom && cistrcmp(sx->sx[0]->data, tag) == 0)
			return sx;
		if(sx->nsx >= 1 && sx->sx[0]->type == SxAtom && strcmp(sx->sx[0]->data, "*") == 0)
			unexpected(z, sx);
		if(sx->type == SxList && sx->nsx == 0){
			freesx(sx);
			break;
		}
		freesx(sx);
	}
	z->connected = 0;
	return nil;
}

/*
 * Imap interface to mail file system.
 */

static void
_bodyname(char *buf, char *ebuf, Part *p, char *extra)
{
	if(buf >= ebuf){
		fprint(2, "***** BUFFER TOO SMALL\n");
		return;
	}
	*buf = 0;
	if(p->parent){
		_bodyname(buf, ebuf, p->parent, "");
		buf += strlen(buf);
		seprint(buf, ebuf, ".%d", p->pix+1);
	}
	buf += strlen(buf);
	seprint(buf, ebuf, "%s", extra);
}

static char*
bodyname(Part *p, char *extra)
{
	static char buf[256];
	memset(buf, 0, sizeof buf);	/* can't see why this is necessary, but it is */
	_bodyname(buf, buf+sizeof buf, p, extra);
	return buf+1;	/* buf[0] == '.' */
}

static void
fetch1(Imap *z, Part *p, char *s)
{
	qlock(&z->lk);
	imapcmd(z, p->msg->box, "UID FETCH %d BODY[%s]", 
		p->msg->imapuid, bodyname(p, s));
	qunlock(&z->lk);
}

void
imapfetchrawheader(Imap *z, Part *p)
{
	fetch1(z, p, ".HEADER");
}

void
imapfetchrawmime(Imap *z, Part *p)
{
	fetch1(z, p, ".MIME");
}

void
imapfetchrawbody(Imap *z, Part *p)
{
	fetch1(z, p, ".TEXT");
}

void
imapfetchraw(Imap *z, Part *p)
{
	fetch1(z, p, "");
}

static int
imaplistcmd(Imap *z, Box *box, char *before, Msg **m, uint nm, char *after)
{
	int i, r;
	char *cmd;
	Fmt fmt;
	
	if(nm == 0)
		return 0;

	fmtstrinit(&fmt);
	fmtprint(&fmt, "%s ", before);
	for(i=0; i<nm; i++){
		if(i > 0)
			fmtrune(&fmt, ',');
		fmtprint(&fmt, "%ud", m[i]->imapuid);
	}
	fmtprint(&fmt, " %s", after);
	cmd = fmtstrflush(&fmt);
	
	r = 0;
	if(imapcmd(z, box, "%s", cmd) < 0)
		 r = -1;
	free(cmd);
	return r;
}

int
imapcopylist(Imap *z, char *nbox, Msg **m, uint nm)
{
	int rv;
	char *name, *p;
	
	if(nm == 0)
		return 0;

	qlock(&z->lk);
	if(strcmp(nbox, "mbox") == 0)
		name = estrdup("INBOX");
	else{
		p = esmprint("%s%s", z->root, nbox);
		name = esmprint("%Z", p);
		free(p);
	}
	rv = imaplistcmd(z, m[0]->box, "UID COPY", m, nm, name);
	free(name);
	qunlock(&z->lk);
	return rv;
}

int
imapremovelist(Imap *z, Msg **m, uint nm)
{
	int rv;
	
	if(nm == 0)
		return 0;

	qlock(&z->lk);
	rv = imaplistcmd(z, m[0]->box, "UID STORE", m, nm, "+FLAGS.SILENT (\\Deleted)");
	/* careful - box might be gone; use z->box instead */
	if(rv == 0 && z->box)
		rv = imapcmd(z, z->box, "EXPUNGE");
	qunlock(&z->lk);
	return rv;
}

int
imapflaglist(Imap *z, int op, int flag, Msg **m, uint nm)
{
	char *mod, *s, *sep;
	int i, rv;
	Fmt fmt;
	
	if(op > 0)
		mod = "+";
	else if(op == 0)
		mod = "";
	else
		mod = "-";

	fmtstrinit(&fmt);
	fmtprint(&fmt, "%sFLAGS (", mod);
	sep = "";
	for(i=0; i<nelem(flagstab); i++){
		if(flagstab[i].flag & flag){
			fmtprint(&fmt, "%s%s", sep, flagstab[i].name);
			sep = " ";
		}
	}
	fmtprint(&fmt, ")");
	s = fmtstrflush(&fmt);
	
	qlock(&z->lk);
	rv = imaplistcmd(z, m[0]->box, "UID STORE", m, nm, s);
	qunlock(&z->lk);
	free(s);
	return rv;
}

int
imapsearchbox(Imap *z, Box *b, char *search, Msg ***mm)
{
	uint *uid;
	int i, nuid;
	Msg **m;
	int nm;

	qlock(&z->lk);
	if(imapcmd(z, b, "UID SEARCH CHARSET UTF-8 TEXT %Z", search) < 0){
		qunlock(&z->lk);
		return -1;
	}

	uid = z->uid;
	nuid = z->nuid;
	z->uid = nil;
	z->nuid = 0;
	qunlock(&z->lk);

	m = emalloc(nuid*sizeof m[0]);
	nm = 0;
	for(i=0; i<nuid; i++)
		if((m[nm] = msgbyimapuid(b, uid[i], 0)) != nil)
			nm++;
	*mm = m;
	free(uid);
	return nm;
}

void
imapcheckbox(Imap *z, Box *b)
{
	if(b == nil)
		return;
	qlock(&z->lk);
	checkbox(z, b);
	qunlock(&z->lk);
}

/*
 * Imap utility routines
 */
static long
_ioimapdial(va_list *arg)
{
	char *server;
	int mode;
	
	server = va_arg(*arg, char*);
	mode = va_arg(*arg, int);
	return imapdial(server, mode);
}
static int
ioimapdial(Ioproc *io, char *server, int mode)
{
	return iocall(io, _ioimapdial, server, mode);
}

static long
_ioBrdsx(va_list *arg)
{
	Biobuf *b;
	Sx **sx;
	
	b = va_arg(*arg, Biobuf*);
	sx = va_arg(*arg, Sx**);
	*sx = Brdsx(b);
	if((*sx) && (*sx)->type == SxList && (*sx)->nsx == 0){
		freesx(*sx);
		*sx = nil;
	}
	return 0;
}
static Sx*
ioBrdsx(Ioproc *io, Biobuf *b)
{
	Sx *sx;

	iocall(io, _ioBrdsx, b, &sx);
	return sx;
}

static Sx*
zBrdsx(Imap *z)
{
	if(z->ticks && --z->ticks==0){
		close(z->fd);
		z->fd = -1;
		return nil;
	}
	return ioBrdsx(z->io, &z->b);
}

static int
imapdial(char *server, int mode)
{
	int p[2];
	int fd[3];
	char *tmp;
	
	switch(mode){
	default:
	case Unencrypted:
		return dial(netmkaddr(server, "tcp", "143"), nil, nil, nil);
		
	case Starttls:
		werrstr("starttls not supported");
		return -1;

	case Tls:
		if(pipe(p) < 0)
			return -1;
		fd[0] = dup(p[0], -1);
		fd[1] = dup(p[0], -1);
		fd[2] = dup(2, -1);
		tmp = esmprint("%s:993", server);
		if(threadspawnl(fd, "/usr/sbin/stunnel", "stunnel", "-c", "-r", tmp, nil) < 0
		    && threadspawnl(fd, "/usr/bin/stunnel", "stunnel", "-c", "-r", tmp, nil) < 0){
			free(tmp);
			close(p[0]);
			close(p[1]);
			close(fd[0]);
			close(fd[1]);
			close(fd[2]);
			return -1;
		}
		free(tmp);
		close(p[0]);
		return p[1];
	
	case Cmd:
		if(pipe(p) < 0)
			return -1;
		fd[0] = dup(p[0], -1);
		fd[1] = dup(p[0], -1);
		fd[2] = dup(2, -1);
		if(threadspawnl(fd, "/usr/local/plan9/bin/rc", "rc", "-c", server, nil) < 0){
			close(p[0]);
			close(p[1]);
			close(fd[0]);
			close(fd[1]);
			close(fd[2]);
			return -1;
		}
		close(p[0]);
		return p[1];
	}
}

enum
{
	Qok = 0,
	Qquote,
	Qbackslash
};

static int
needtoquote(Rune r)
{
	if(r >= Runeself)
		return Qquote;
	if(r <= ' ')
		return Qquote;
	if(r=='\\' || r=='"')
		return Qbackslash;
	return Qok;
}

static int
imapquote(Fmt *f)
{
	char *s, *t;
	int w, quotes;
	Rune r;

	s = va_arg(f->args, char*);
	if(s == nil || *s == '\0')
		return fmtstrcpy(f, "\"\"");

	quotes = 0;
	if(f->flags&FmtSharp)
		quotes = 1;
	for(t=s; *t; t+=w){
		w = chartorune(&r, t);
		quotes |= needtoquote(r);
	}
	if(quotes == 0)
		return fmtstrcpy(f, s);

	fmtrune(f, '"');
	for(t=s; *t; t+=w){
		w = chartorune(&r, t);
		if(needtoquote(r) == Qbackslash)
			fmtrune(f, '\\');
		fmtrune(f, r);
	}
	return fmtrune(f, '"');
}

static int
fmttype(char c)
{
	switch(c){
	case 'A':
		return SxAtom;
	case 'L':
		return SxList;
	case 'N':
		return SxNumber;
	case 'S':
		return SxString;
	default:
		return -1;
	}
}

/*
 * Check S expression against format string.
 */
static int
sxmatch(Sx *sx, char *fmt)
{
	int i;
	
	for(i=0; fmt[i]; i++){
		if(fmt[i] == '*')
			fmt--;	/* like i-- but better */
		if(i == sx->nsx && fmt[i+1] == '*')
			return 1;
		if(i >= sx->nsx)
			return 0;
		if(sx->sx[i] == nil)
			return 0;
		if(sx->sx[i]->type == SxAtom && strcmp(sx->sx[i]->data, "NIL") == 0){
			if(fmt[i] == 'L'){
				free(sx->sx[i]->data);
				sx->sx[i]->data = nil;
				sx->sx[i]->type = SxList;
				sx->sx[i]->sx = nil;
				sx->sx[i]->nsx = 0;
			}
			else if(fmt[i] == 'S'){
				free(sx->sx[i]->data);
				sx->sx[i]->data = nil;
				sx->sx[i]->type = SxString;
			}
		}
		if(sx->sx[i]->type == SxAtom && fmt[i]=='S')
			sx->sx[i]->type = SxString;
		if(sx->sx[i]->type != fmttype(fmt[i])){
			fprint(2, "sxmatch: %$ not %c\n", sx->sx[i], fmt[i]);
			return 0;
		}
	}
	if(i != sx->nsx)
		return 0;
	return 1;
}

/*
 * Check string against format string.
 */
static int
stringmatch(char *fmt, char *s)
{
	for(; *fmt && *s; fmt++, s++){
		switch(*fmt){
		case '0':
			if(*s == ' ')
				break;
			/* fall through */
		case '1':
			if(*s < '0' || *s > '9')
				return 0;
			break;
		case 'A':
			if(*s < 'A' || *s > 'Z')
				return 0;
			break;
		case 'a':
			if(*s < 'a' || *s > 'z')
				return 0;
			break;
		case '+':
			if(*s != '-' && *s != '+')
				return 0;
			break;
		default:
			if(*s != *fmt)
				return 0;
			break;
		}
	}
	if(*fmt || *s)
		return 0;
	return 1;
}

/*
 * Parse simple S expressions and IMAP elements.
 */
static int
isatom(Sx *v, char *name)
{
	int n;
	
	if(v == nil || v->type != SxAtom)
		return 0;
	n = strlen(name);
	if(cistrncmp(v->data, name, n) == 0)
		if(v->data[n] == 0 || (n>0 && v->data[n-1] == '['))
			return 1;
	return 0;
}

static int
isstring(Sx *sx)
{
	if(sx->type == SxAtom)
		sx->type = SxString;
	return sx->type == SxString;
}

static int
isnumber(Sx *sx)
{
	return sx->type == SxNumber;
}

static int
isnil(Sx *v)
{
	return v == nil || 
		(v->type==SxList && v->nsx == 0) ||
		(v->type==SxAtom && strcmp(v->data, "NIL") == 0);
}

static int
islist(Sx *v)
{
	return isnil(v) || v->type==SxList;
}

static uint
parseflags(Sx *v)
{
	int f, i, j;
	
	if(v->type != SxList){
		warn("malformed flags: %$", v);
		return 0;
	}
	f = 0;
	for(i=0; i<v->nsx; i++){
		if(v->sx[i]->type != SxAtom)
			continue;
		for(j=0; j<nelem(flagstab); j++)
			if(cistrcmp(v->sx[i]->data, flagstab[j].name) == 0)
				f |= flagstab[j].flag;
	}
	return f;
}
	
static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
static int
parsemon(char *s)
{
	int i;
	
	for(i=0; months[i]; i+=3)
		if(memcmp(s, months+i, 3) == 0)
			return i/3;
	return -1;
}

static uint
parsedate(Sx *v)
{
	Tm tm;
	uint t;
	int delta;
	char *p;
	
	if(v->type != SxString || !stringmatch("01-Aaa-1111 01:11:11 +1111", v->data)){
	bad:
		warn("bad date: %$", v);
		return 0;
	}
	
	/* cannot use atoi because 09 is malformed octal! */
	memset(&tm, 0, sizeof tm);
	p = v->data;
	tm.mday = strtol(p, 0, 10);
	tm.mon = parsemon(p+3);
	if(tm.mon == -1)
		goto bad;
	tm.year = strtol(p+7, 0, 10) - 1900;
	tm.hour = strtol(p+12, 0, 10);
	tm.min = strtol(p+15, 0, 10);
	tm.sec = strtol(p+18, 0, 10);
	strcpy(tm.zone, "GMT");

	t = tm2sec(&tm);
	delta = ((p[22]-'0')*10+p[23]-'0')*3600 + ((p[24]-'0')*10+p[25]-'0')*60;
	if(p[21] == '-')
		delta = -delta;
	
	t -= delta;
	return t;
}

static uint
parsenumber(Sx *v)
{
	if(v->type != SxNumber)
		return 0;
	return v->number;
}

static void
hash(DigestState *ds, char *tag, char *val)
{
	if(val == nil)
		val = "";
	md5((uchar*)tag, strlen(tag)+1, nil, ds);
	md5((uchar*)val, strlen(val)+1, nil, ds);
}

static Hdr*
parseenvelope(Sx *v)
{
	Hdr *hdr;
	uchar digest[16];
	DigestState ds;
	
	if(v->type != SxList || !sxmatch(v, "SSLLLLLLSS")){
		warn("bad envelope: %$", v);
		return nil;
	}

	hdr = emalloc(sizeof *hdr);
	hdr->date = nstring(v->sx[0]);
	hdr->subject = unrfc2047(nstring(v->sx[1]));
	hdr->from = copyaddrs(v->sx[2]);
	hdr->sender = copyaddrs(v->sx[3]);
	hdr->replyto = copyaddrs(v->sx[4]);
	hdr->to = copyaddrs(v->sx[5]);
	hdr->cc = copyaddrs(v->sx[6]);
	hdr->bcc = copyaddrs(v->sx[7]);
	hdr->inreplyto = unrfc2047(nstring(v->sx[8]));
	hdr->messageid = unrfc2047(nstring(v->sx[9]));
	
	memset(&ds, 0, sizeof ds);
	hash(&ds, "date", hdr->date);
	hash(&ds, "subject", hdr->subject);
	hash(&ds, "from", hdr->from);
	hash(&ds, "sender", hdr->sender);
	hash(&ds, "replyto", hdr->replyto);
	hash(&ds, "to", hdr->to);
	hash(&ds, "cc", hdr->cc);
	hash(&ds, "bcc", hdr->bcc);
	hash(&ds, "inreplyto", hdr->inreplyto);
	hash(&ds, "messageid", hdr->messageid);
	md5(0, 0, digest, &ds);
	hdr->digest = esmprint("%.16H", digest);

	return hdr;
}

static void
strlwr(char *s)
{
	char *t;
	
	if(s == nil)
		return;
	for(t=s; *t; t++)
		if('A' <= *t && *t <= 'Z')
			*t += 'a' - 'A';
}

static void
nocr(char *s)
{
	char *r, *w;
	
	if(s == nil)
		return;
	for(r=w=s; *r; r++)
		if(*r != '\r')
			*w++ = *r;
	*w = 0;
}

/*
 * substitute all occurrences of a with b in s.
 */
static char*
gsub(char *s, char *a, char *b)
{
	char *p, *t, *w, *last;
	int n;
	
	n = 0;
	for(p=s; (p=strstr(p, a)) != nil; p+=strlen(a))
		n++;
	if(n == 0)
		return s;
	t = emalloc(strlen(s)+n*strlen(b)+1);
	w = t;
	for(p=s; last=p, (p=strstr(p, a)) != nil; p+=strlen(a)){
		memmove(w, last, p-last);
		w += p-last;
		memmove(w, b, strlen(b));
		w += strlen(b);
	}
	strcpy(w, last);
	free(s);
	return t;
}

/*
 * Table-driven IMAP "unexpected response" parser.
 * All the interesting data is in the unexpected responses.
 */
static void xlist(Imap*, Sx*);
static void xrecent(Imap*, Sx*);
static void xexists(Imap*, Sx*);
static void xok(Imap*, Sx*);
static void xflags(Imap*, Sx*);
static void xfetch(Imap*, Sx*);
static void xexpunge(Imap*, Sx*);
static void xbye(Imap*, Sx*);
static void xsearch(Imap*, Sx*);

static struct {
	int		num;
	char		*name;
	char		*fmt;
	void		(*fn)(Imap*, Sx*);
} unextab[] = {
	0,	"BYE",		nil,			xbye,
	0,	"FLAGS",		"AAL",		xflags,
	0,	"LIST",		"AALSS",		xlist,
	0,	"OK",		nil,			xok,
	0,	"SEARCH",	"AAN*",		xsearch,

	1,	"EXISTS",		"ANA",		xexists,
	1,	"EXPUNGE",	"ANA",		xexpunge,
	1,	"FETCH",		"ANAL",		xfetch,
	1,	"RECENT",	"ANA",		xrecent
};

static void
unexpected(Imap *z, Sx *sx)
{
	int i, num;
	char *name;

	if(sx->nsx >= 3 && sx->sx[1]->type == SxNumber && sx->sx[2]->type == SxAtom){
		num = 1;
		name = sx->sx[2]->data;
	}else if(sx->nsx >= 2 && sx->sx[1]->type == SxAtom){
		num = 0;
		name = sx->sx[1]->data;
	}else
		return;
	
	for(i=0; i<nelem(unextab); i++){
		if(unextab[i].num == num && cistrcmp(unextab[i].name, name) == 0){
			if(unextab[i].fmt && !sxmatch(sx, unextab[i].fmt)){
				warn("malformed %s: %$", name, sx);
				continue;
			}
			unextab[i].fn(z, sx);
		}
	}
}

static int
alldollars(char *s)
{
	for(; *s; s++)
		if(*s != '$')
			return 0;
	return 1;
}

static void
xlist(Imap *z, Sx *sx)
{
	int inbox;
	char *s, *t;
	Box *box;

	s = estrdup(sx->sx[4]->data);
	if(sx->sx[3]->data && strcmp(sx->sx[3]->data, "/") != 0){
		s = gsub(s, "/", "_");
		s = gsub(s, sx->sx[3]->data, "/");
	}

	/*
	 * INBOX is the special imap name for the main mailbox.
	 * All other mailbox names have the root prefix removed, if applicable.
	 */
	inbox = 0;
	if(cistrcmp(s, "INBOX") == 0){
		inbox = 1;
		free(s);
		s = estrdup("mbox");
	} else if(z->root && strstr(s, z->root) == s) {
		t = estrdup(s+strlen(z->root));
		free(s);
		s = t;
	}
	
	/* 
	 * Plan 9 calls the main mailbox mbox.  
	 * Rename any existing mbox by appending a $.
	 */
	if(!inbox && strncmp(s, "mbox", 4) == 0 && alldollars(s+4)){
		t = emalloc(strlen(s)+2);
		strcpy(t, s);
		strcat(t, "$");
		free(s);
		s = t;
	}

	box = boxcreate(s);
	if(box == nil)
		return;
	box->imapname = estrdup(sx->sx[4]->data);
	if(inbox)
		z->inbox = box;
	box->mark = 0;
	box->flags = parseflags(sx->sx[2]);
}

static void
xrecent(Imap *z, Sx *sx)
{
	if(z->box)
		z->box->recent = sx->sx[1]->number;
}

static void
xexists(Imap *z, Sx *sx)
{
	if(z->box){
		z->box->exists = sx->sx[1]->number;
		if(z->box->exists < z->box->maxseen)
			z->box->maxseen = z->box->exists;
	}
}

static void
xflags(Imap *z, Sx *sx)
{
	/*
	 * This response contains in sx->sx[2] the list of flags
	 * that can be validly attached to messages in z->box.
	 * We don't have any use for this list, since we 
	 * use only the standard flags.
	 */
}

static void
xbye(Imap *z, Sx *sx)
{
	close(z->fd);
	z->fd = -1;
	z->connected = 0;
}

static void
xexpunge(Imap *z, Sx *sx)
{
	int i, n;
	Box *b;

	if((b=z->box) == nil)
		return;
	n = sx->sx[1]->number;
	for(i=0; i<b->nmsg; i++){
		if(b->msg[i]->imapid == n){
			msgplumb(b->msg[i], 1);
			msgfree(b->msg[i]);
			b->nmsg--;
			memmove(b->msg+i, b->msg+i+1, (b->nmsg-i)*sizeof b->msg[0]);
			i--;
			b->maxseen--;
			b->exists--;
			continue;
		}
		if(b->msg[i]->imapid > n)
			b->msg[i]->imapid--;
		b->msg[i]->ix = i;
	}
}

static void
xsearch(Imap *z, Sx *sx)
{
	int i;
	
	free(z->uid);
	z->uid = emalloc((sx->nsx-2)*sizeof z->uid[0]);
	z->nuid = sx->nsx-2;
	for(i=0; i<z->nuid; i++)
		z->uid[i] = sx->sx[i+2]->number;
}

/* 
 * Table-driven FETCH message info parser.
 */
static void xmsgflags(Msg*, Sx*, Sx*);
static void xmsgdate(Msg*, Sx*, Sx*);
static void xmsgrfc822size(Msg*, Sx*, Sx*);
static void xmsgenvelope(Msg*, Sx*, Sx*);
static void xmsgbody(Msg*, Sx*, Sx*);
static void xmsgbodydata(Msg*, Sx*, Sx*);

static struct {
	char *name;
	void (*fn)(Msg*, Sx*, Sx*);
} msgtab[] = {
	"FLAGS", xmsgflags,
	"INTERNALDATE", xmsgdate,
	"RFC822.SIZE", xmsgrfc822size,
	"ENVELOPE", xmsgenvelope,
	"BODY", xmsgbody,
	"BODY[", xmsgbodydata
};

static void
xfetch(Imap *z, Sx *sx)
{
	int i, j, n, uid;
	Msg *msg;

	if(z->box == nil){
		warn("FETCH but no open box: %$", sx);
		return;
	}

	/* * 152 FETCH (UID 185 FLAGS () ...) */
	if(sx->sx[3]->nsx%2){
		warn("malformed FETCH: %$", sx);
		return;
	}

	n = sx->sx[1]->number;
	sx = sx->sx[3];
	for(i=0; i<sx->nsx; i+=2){
		if(isatom(sx->sx[i], "UID")){
			if(sx->sx[i+1]->type == SxNumber){
				uid = sx->sx[i+1]->number;
				goto haveuid;
			}
		}
	}
/* This happens: too bad.
	warn("FETCH without UID: %$", sx);
*/
	return;

haveuid:
	msg = msgbyimapuid(z->box, uid, 1);
	if(msg->imapid && msg->imapid != n)
		warn("msg id mismatch: want %d have %d", msg->id, n);
	msg->imapid = n;
	for(i=0; i<sx->nsx; i+=2){
		for(j=0; j<nelem(msgtab); j++)
			if(isatom(sx->sx[i], msgtab[j].name))
				msgtab[j].fn(msg, sx->sx[i], sx->sx[i+1]);
	}
}

static void
xmsgflags(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->flags = parseflags(v);
}

static void
xmsgdate(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->date = parsedate(v);
}

static void
xmsgrfc822size(Msg *msg, Sx *k, Sx *v)
{
	USED(k);
	msg->size = parsenumber(v);
}

static char*
nstring(Sx *v)
{
	char *p;
	
	if(isnil(v))
		return estrdup("");
	p = v->data;
	v->data = nil;
	return p;
}

static char*
copyaddrs(Sx *v)
{
	char *s, *sep;
	char *name, *email, *host, *mbox;
	int i;
	Fmt fmt;
	
	if(v->nsx == 0)
		return nil;

	fmtstrinit(&fmt);
	sep = "";
	for(i=0; i<v->nsx; i++){
		if(!sxmatch(v->sx[i], "SSSS"))
			warn("bad address: %$", v->sx[i]);
		name = unrfc2047(nstring(v->sx[i]->sx[0]));
		/* ignore sx[1] - route */
		mbox = unrfc2047(nstring(v->sx[i]->sx[2]));
		host = unrfc2047(nstring(v->sx[i]->sx[3]));
		if(mbox == nil || host == nil){	/* rfc822 group syntax */
			free(name);
			free(mbox);
			free(host);
			continue;
		}
		email = esmprint("%s@%s", mbox, host);
		free(mbox);
		free(host);
		fmtprint(&fmt, "%s%q %q", sep, name ? name : "", email ? email : "");
		free(name);
		free(email);
		sep = " ";
	}
	s = fmtstrflush(&fmt);
	if(s == nil)
		sysfatal("out of memory");
	return s;
}

static void
xmsgenvelope(Msg *msg, Sx *k, Sx *v)
{
	hdrfree(msg->part[0]->hdr);
	msg->part[0]->hdr = parseenvelope(v);
	msgplumb(msg, 0);
}

static struct {
	char *name;
	int offset;
} paramtab[] = {
	"charset",	offsetof(Part, charset),
	"name",		offsetof(Part, filename)
};

static void
parseparams(Part *part, Sx *v)
{
	int i, j;
	char *s, *t, **p;
	
	if(isnil(v))
		return;
	if(v->nsx%2){
		warn("bad message params: %$", v);
		return;
	}
	for(i=0; i<v->nsx; i+=2){
		s = nstring(v->sx[i]);
		t = nstring(v->sx[i+1]);
		for(j=0; j<nelem(paramtab); j++){
			if(cistrcmp(paramtab[j].name, s) == 0){
				p = (char**)((char*)part+paramtab[j].offset);
				free(*p);
				*p = t;
				t = nil;
				break;
			}
		}
		free(s);
		free(t);
	}			
}

static void
parsestructure(Part *part, Sx *v)
{
	int i;
	char *s, *t;
	
	if(isnil(v))
		return;
	if(v->type != SxList){
	bad:
		warn("bad structure: %$", v);
		return;
	}
	if(islist(v->sx[0])){
		/* multipart */
		for(i=0; i<v->nsx && islist(v->sx[i]); i++)
			parsestructure(partcreate(part->msg, part), v->sx[i]);
		free(part->type);
		if(i != v->nsx-1 || !isstring(v->sx[i])){
			warn("bad multipart structure: %$", v);
			part->type = estrdup("multipart/mixed");
			return;
		}
		s = nstring(v->sx[i]);
		strlwr(s);
		part->type = esmprint("multipart/%s", s);
		free(s);
		return;
	}
	/* single part */
	if(!isstring(v->sx[0]) || v->nsx < 2)
		goto bad;
	s = nstring(v->sx[0]);
	t = nstring(v->sx[1]);
	strlwr(s);
	strlwr(t);
	free(part->type);
	part->type = esmprint("%s/%s", s, t);
	if(v->nsx < 7 || !islist(v->sx[2]) || !isstring(v->sx[3]) 
	|| !isstring(v->sx[4]) || !isstring(v->sx[5]) || !isnumber(v->sx[6]))
		goto bad;
	parseparams(part, v->sx[2]);
	part->idstr = nstring(v->sx[3]);
	part->desc = nstring(v->sx[4]);
	part->encoding = nstring(v->sx[5]);
	part->size = v->sx[6]->number;
	if(strcmp(s, "message") == 0 && strcmp(t, "rfc822") == 0){
		if(v->nsx < 10 || !islist(v->sx[7]) || !islist(v->sx[8]) || !isnumber(v->sx[9]))
			goto bad;
		part->hdr = parseenvelope(v->sx[7]);
		parsestructure(partcreate(part->msg, part), v->sx[8]);
		part->lines = v->sx[9]->number;
	}
	if(strcmp(s, "text") == 0){
		if(v->nsx < 8 || !isnumber(v->sx[7]))
			goto bad;
		part->lines = v->sx[7]->number;
	}
}

static void
xmsgbody(Msg *msg, Sx *k, Sx *v)
{
	if(v->type != SxList){
		warn("bad body: %$", v);
		return;
	}
	/*
	 * To follow the structure exactly we should
	 * be doing this to partcreate(msg, msg->part[0]),
	 * and we should leave msg->part[0] with type message/rfc822,
	 * but the extra layer is redundant - what else would be in a mailbox?
	 */
	parsestructure(msg->part[0], v);
	if(msg->box->maxseen < msg->imapid)
		msg->box->maxseen = msg->imapid;
	if(msg->imapuid >= msg->box->uidnext)
		msg->box->uidnext = msg->imapuid+1;
}

static void
xmsgbodydata(Msg *msg, Sx *k, Sx *v)
{
	int i;
	char *name, *p;
	Part *part;
	
	name = k->data;
	name += 5;	/* body[ */
	p = strchr(name, ']');
	if(p)
		*p = 0;
	
	/* now name is something like 1 or 3.2.MIME - walk down parts from root */
	part = msg->part[0];


	while('1' <= name[0] && name[0] <= '9'){
		i = strtol(name, &p, 10);
		if(*p == '.')
			p++;
		else if(*p != 0){
			warn("bad body name: %$", k);
			return;
		}
		if((part = subpart(part, i-1)) == nil){
			warn("unknown body part: %$", k);
			return;
		}
		name = p;
	}


	if(cistrcmp(name, "") == 0){
		free(part->raw);
		part->raw = nstring(v);
		nocr(part->raw);
	}else if(cistrcmp(name, "HEADER") == 0){
		free(part->rawheader);
		part->rawheader = nstring(v);
		nocr(part->rawheader);
	}else if(cistrcmp(name, "MIME") == 0){
		free(part->mimeheader);
		part->mimeheader = nstring(v);
		nocr(part->mimeheader);
	}else if(cistrcmp(name, "TEXT") == 0){
		free(part->rawbody);
		part->rawbody = nstring(v);
		nocr(part->rawbody);
	}
}

/*
 * Table-driven OK info parser.
 */
static void xokuidvalidity(Imap*, Sx*);
static void xokpermflags(Imap*, Sx*);
static void xokunseen(Imap*, Sx*);
static void xokreadwrite(Imap*, Sx*);
static void xokreadonly(Imap*, Sx*);

struct {
	char *name;
	char fmt;
	void (*fn)(Imap*, Sx*);
} oktab[] = {
	"UIDVALIDITY", 'N',	xokuidvalidity,
	"PERMANENTFLAGS", 'L',	xokpermflags,
	"UNSEEN", 'N',	xokunseen,
	"READ-WRITE", 0,	xokreadwrite,
	"READ-ONLY",	0, xokreadonly
};

static void
xok(Imap *z, Sx *sx)
{
	int i;
	char *name;
	Sx *arg;

	if(sx->nsx >= 4 && sx->sx[2]->type == SxAtom && sx->sx[2]->data[0] == '['){
		if(sx->sx[3]->type == SxAtom && sx->sx[3]->data[0] == ']')
			arg = nil;
		else if(sx->sx[4]->type == SxAtom && sx->sx[4]->data[0] == ']')
			arg = sx->sx[3];
		else{
			warn("cannot parse OK: %$", sx);
			return;
		}
		name = sx->sx[2]->data+1;
		for(i=0; i<nelem(oktab); i++){
			if(cistrcmp(name, oktab[i].name) == 0){
				if(oktab[i].fmt && (arg==nil || arg->type != fmttype(oktab[i].fmt))){
					warn("malformed %s: %$", name, arg);
					continue;
				}
				oktab[i].fn(z, arg);
			}
		}
	}
}

static void
xokuidvalidity(Imap *z, Sx *sx)
{
	int i;
	Box *b;
	
	if((b=z->box) == nil)
		return;
	if(b->validity != sx->number){
		b->validity = sx->number;
		b->uidnext = 1;
		for(i=0; i<b->nmsg; i++)
			msgfree(b->msg[i]);
		free(b->msg);
		b->msg = nil;
		b->nmsg = 0;
	}
}

static void
xokpermflags(Imap *z, Sx *sx)
{
/*	z->permflags = parseflags(sx); */
}

static void
xokunseen(Imap *z, Sx *sx)
{
/*	z->unseen = sx->number; */
}

static void
xokreadwrite(Imap *z, Sx *sx)
{
/*	z->boxmode = ORDWR; */
}

static void
xokreadonly(Imap *z, Sx *sx)
{
/*	z->boxmode = OREAD; */
}

