#include "common.h"
#include <ctype.h>
#include <plumb.h>
#include <libsec.h>
#include "dat.h"

enum {
	Buffersize = 64*1024,
};

typedef struct Inbuf Inbuf;
struct Inbuf
{
	int	fd;
	uchar	*lim;
	uchar	*rptr;
	uchar	*wptr;
	uchar	data[Buffersize+7];
};

static void
addtomessage(Message *m, uchar *p, int n, int done)
{
	int i, len;

	// add to message (+ 1 in malloc is for a trailing null)
	if(m->lim - m->end < n){
		if(m->start != nil){
			i = m->end-m->start;
			if(done)
				len = i + n;
			else
				len = (4*(i+n))/3;
			m->start = erealloc(m->start, len + 1);
			m->end = m->start + i;
		} else {
			if(done)
				len = n;
			else
				len = 2*n;
			m->start = emalloc(len + 1);
			m->end = m->start;
		}
		m->lim = m->start + len;
	}

	memmove(m->end, p, n);
	m->end += n;
}

//
//  read in a single message
//
static int
readmessage(Message *m, Inbuf *inb)
{
	int i, n, done;
	uchar *p, *np;
	char sdigest[SHA1dlen*2+1];
	char tmp[64];

	for(done = 0; !done;){
		n = inb->wptr - inb->rptr;
		if(n < 6){
			if(n)
				memmove(inb->data, inb->rptr, n);
			inb->rptr = inb->data;
			inb->wptr = inb->rptr + n;
			i = read(inb->fd, inb->wptr, Buffersize);
			if(i < 0){
				/* if(fd2path(inb->fd, tmp, sizeof tmp) < 0)
					strcpy(tmp, "unknown mailbox");  jpc */
				fprint(2, "error reading '%s': %r\n", tmp);
				return -1;
			}
			if(i == 0){
				if(n != 0)
					addtomessage(m, inb->rptr, n, 1);
				if(m->end == m->start)
					return -1;
				break;
			}
			inb->wptr += i;
		}

		// look for end of message
		for(p = inb->rptr; p < inb->wptr; p = np+1){
			// first part of search for '\nFrom '
			np = memchr(p, '\n', inb->wptr - p);
			if(np == nil){
				p = inb->wptr;
				break;
			}

			/*
			 *  if we've found a \n but there's
			 *  not enough room for '\nFrom ', don't do
			 *  the comparison till we've read in more.
			 */
			if(inb->wptr - np < 6){
				p = np;
				break;
			}

			if(strncmp((char*)np, "\nFrom ", 6) == 0){
				done = 1;
				p = np+1;
				break;
			}
		}

		// add to message (+ 1 in malloc is for a trailing null)
		n = p - inb->rptr;
		addtomessage(m, inb->rptr, n, done);
		inb->rptr += n;
	}

	// if it doesn't start with a 'From ', this ain't a mailbox
	if(strncmp(m->start, "From ", 5) != 0)
		return -1;

	// dump trailing newline, make sure there's a trailing null
	// (helps in body searches)
	if(*(m->end-1) == '\n')
		m->end--;
	*m->end = 0;
	m->bend = m->rbend = m->end;

	// digest message
	sha1((uchar*)m->start, m->end - m->start, m->digest, nil);
	for(i = 0; i < SHA1dlen; i++)
		sprint(sdigest+2*i, "%2.2ux", m->digest[i]);
	m->sdigest = s_copy(sdigest);

	return 0;
}


// throw out deleted messages.  return number of freshly deleted messages
int
purgedeleted(Mailbox *mb)
{
	Message *m, *next;
	int newdels;

	// forget about what's no longer in the mailbox
	newdels = 0;
	for(m = mb->root->part; m != nil; m = next){
		next = m->next;
		if(m->deleted && m->refs == 0){
			if(m->inmbox)
				newdels++;
			delmessage(mb, m);
		}
	}
	return newdels;
}

//
//  read in the mailbox and parse into messages.
//
static char*
_readmbox(Mailbox *mb, int doplumb, Mlock *lk)
{
	int fd;
	String *tmp;
	Dir *d;
	static char err[128];
	Message *m, **l;
	Inbuf *inb;
	char *x;

	l = &mb->root->part;

	/*
	 *  open the mailbox.  If it doesn't exist, try the temporary one.
	 */
retry:
	fd = open(mb->path, OREAD);
	if(fd < 0){
		errstr(err, sizeof(err));
		if(strstr(err, "exist") != 0){
			tmp = s_copy(mb->path);
			s_append(tmp, ".tmp");
			if(sysrename(s_to_c(tmp), mb->path) == 0){
				s_free(tmp);
				goto retry;
			}
			s_free(tmp);
		}
		return err;
	}

	/*
	 *  a new qid.path means reread the mailbox, while
	 *  a new qid.vers means read any new messages
	 */
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		errstr(err, sizeof(err));
		return err;
	}
	if(mb->d != nil){
		if(d->qid.path == mb->d->qid.path && d->qid.vers == mb->d->qid.vers){
			close(fd);
			free(d);
			return nil;
		}
		if(d->qid.path == mb->d->qid.path){
			while(*l != nil)
				l = &(*l)->next;
			seek(fd, mb->d->length, 0);
		}
		free(mb->d);
	}
	mb->d = d;
	mb->vers++;
	henter(PATH(0, Qtop), mb->name,
		(Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb);

	inb = emalloc(sizeof(Inbuf));
	inb->rptr = inb->wptr = inb->data;
	inb->fd = fd;

	//  read new messages
	snprint(err, sizeof err, "reading '%s'", mb->path);
	logmsg(err, nil);
	for(;;){
		if(lk != nil)
			syslockrefresh(lk);
		m = newmessage(mb->root);
		m->mallocd = 1;
		m->inmbox = 1;
		if(readmessage(m, inb) < 0){
			delmessage(mb, m);
			mb->root->subname--;
			break;
		}

		// merge mailbox versions
		while(*l != nil){
			if(memcmp((*l)->digest, m->digest, SHA1dlen) == 0){
				// matches mail we already read, discard
				logmsg("duplicate", *l);
				delmessage(mb, m);
				mb->root->subname--;
				m = nil;
				l = &(*l)->next;
				break;
			} else {
				// old mail no longer in box, mark deleted
				logmsg("disappeared", *l);
				if(doplumb)
					mailplumb(mb, *l, 1);
				(*l)->inmbox = 0;
				(*l)->deleted = 1;
				l = &(*l)->next;
			}
		}
		if(m == nil)
			continue;

		x = strchr(m->start, '\n');
		if(x == nil)
			m->header = m->end;
		else
			m->header = x + 1;
		m->mheader = m->mhend = m->header;
		parseunix(m);
		parse(m, 0, mb, 0);
		logmsg("new", m);

		/* chain in */
		*l = m;
		l = &m->next;
		if(doplumb)
			mailplumb(mb, m, 0);

	}
	logmsg("mbox read", nil);

	// whatever is left has been removed from the mbox, mark deleted
	while(*l != nil){
		if(doplumb)
			mailplumb(mb, *l, 1);
		(*l)->inmbox = 0;
		(*l)->deleted = 1;
		l = &(*l)->next;
	}

	close(fd);
	free(inb);
	return nil;
}

static void
_writembox(Mailbox *mb, Mlock *lk)
{
	Dir *d;
	Message *m;
	String *tmp;
	int mode, errs;
	Biobuf *b;

	tmp = s_copy(mb->path);
	s_append(tmp, ".tmp");

	/*
	 * preserve old files permissions, if possible
	 */
	d = dirstat(mb->path);
	if(d != nil){
		mode = d->mode&0777;
		free(d);
	} else
		mode = MBOXMODE;

	sysremove(s_to_c(tmp));
	b = sysopen(s_to_c(tmp), "alc", mode);
	if(b == 0){
		fprint(2, "can't write temporary mailbox %s: %r\n", s_to_c(tmp));
		return;
	}

	logmsg("writing new mbox", nil);
	errs = 0;
	for(m = mb->root->part; m != nil; m = m->next){
		if(lk != nil)
			syslockrefresh(lk);
		if(m->deleted)
			continue;
		logmsg("writing", m);
		if(Bwrite(b, m->start, m->end - m->start) < 0)
			errs = 1;
		if(Bwrite(b, "\n", 1) < 0)
			errs = 1;
	}
	logmsg("wrote new mbox", nil);

	if(sysclose(b) < 0)
		errs = 1;

	if(errs){
		fprint(2, "error writing temporary mail file\n");
		s_free(tmp);
		return;
	}

	sysremove(mb->path);
	if(sysrename(s_to_c(tmp), mb->path) < 0)
		fprint(2, "%s: can't rename %s to %s: %r\n", argv0,
			s_to_c(tmp), mb->path);
	s_free(tmp);
	if(mb->d != nil)
		free(mb->d);
	mb->d = dirstat(mb->path);
}

char*
plan9syncmbox(Mailbox *mb, int doplumb)
{
	Mlock *lk;
	char *rv;

	lk = nil;
	if(mb->dolock){
		lk = syslock(mb->path);
		if(lk == nil)
			return "can't lock mailbox";
	}

	rv = _readmbox(mb, doplumb, lk);		/* interpolate */
	if(purgedeleted(mb) > 0)
		_writembox(mb, lk);

	if(lk != nil)
		sysunlock(lk);

	return rv;
}

//
//  look to see if we can open this mail box
//
char*
plan9mbox(Mailbox *mb, char *path)
{
	static char err[64];
	String *tmp;

	if(access(path, AEXIST) < 0){
		errstr(err, sizeof(err));
		tmp = s_copy(path);
		s_append(tmp, ".tmp");
		if(access(s_to_c(tmp), AEXIST) < 0){
			s_free(tmp);
			return err;
		}
		s_free(tmp);
	}

	mb->sync = plan9syncmbox;
	return nil;
}
