#include <u.h>
#include <libc.h>
#include <bio.h>
#include <regexp.h>
#include <thread.h>
#include <fcall.h>
#include <plumb.h>
#include "plumber.h"

enum
{
	Stack = 32*1024
};

typedef struct Dirtab Dirtab;
typedef struct Fid Fid;
typedef struct Holdq Holdq;
typedef struct Readreq Readreq;
typedef struct Sendreq Sendreq;

struct Dirtab
{
	char		*name;
	uchar	type;
	uint		qid;
	uint		perm;
	int		nopen;		/* #fids open on this port */
	Fid		*fopen;
	Holdq	*holdq;
	Readreq	*readq;
	Sendreq	*sendq;
};

struct Fid
{
	int		fid;
	int		busy;
	int		open;
	int		mode;
	Qid		qid;
	Dirtab	*dir;
	long		offset;		/* zeroed at beginning of each message, read or write */
	char		*writebuf;		/* partial message written so far; offset tells how much */
	Fid		*next;
	Fid		*nextopen;
};

struct Readreq
{
	Fid		*fid;
	Fcall		*fcall;
	uchar	*buf;
	Readreq	*next;
};

struct Sendreq
{
	int			nfid;		/* number of fids that should receive this message */
	int			nleft;		/* number left that haven't received it */
	Fid			**fid;	/* fid[nfid] */
	Plumbmsg	*msg;
	char			*pack;	/* plumbpack()ed message */
	int			npack;	/* length of pack */
	Sendreq		*next;
};

struct Holdq
{
	Plumbmsg	*msg;
	Holdq		*next;
};

struct	/* needed because incref() doesn't return value */
{
	Lock	lk;
	int	ref;
} rulesref;

enum
{
	NDIR	= 50,
	Nhash	= 16,

	Qdir		= 0,
	Qrules	= 1,
	Qsend	= 2,
	Qport	= 3,
	NQID	= Qport
};

static Dirtab dir[NDIR] =
{
	{ ".",			QTDIR,	Qdir,			0500|DMDIR },
	{ "rules",		QTFILE,	Qrules,		0600 },
	{ "send",		QTFILE,	Qsend,		0200 }
};
static int	ndir = NQID;

static int		srvfd;
#define clock plumbclock	/* SunOS name clash */
static int		clock;
static Fid		*fids[Nhash];
static QLock	readlock;
static QLock	queue;
static int		messagesize = 8192+IOHDRSZ;	/* good start */

static void	fsysproc(void*);
static void fsysrespond(Fcall*, uchar*, char*);
static Fid*	newfid(int);

static Fcall* fsysflush(Fcall*, uchar*, Fid*);
static Fcall* fsysversion(Fcall*, uchar*, Fid*);
static Fcall* fsysauth(Fcall*, uchar*, Fid*);
static Fcall* fsysattach(Fcall*, uchar*, Fid*);
static Fcall* fsyswalk(Fcall*, uchar*, Fid*);
static Fcall* fsysopen(Fcall*, uchar*, Fid*);
static Fcall* fsyscreate(Fcall*, uchar*, Fid*);
static Fcall* fsysread(Fcall*, uchar*, Fid*);
static Fcall* fsyswrite(Fcall*, uchar*, Fid*);
static Fcall* fsysclunk(Fcall*, uchar*, Fid*);
static Fcall* fsysremove(Fcall*, uchar*, Fid*);
static Fcall* fsysstat(Fcall*, uchar*, Fid*);
static Fcall* fsyswstat(Fcall*, uchar*, Fid*);

Fcall* 	(*fcall[Tmax])(Fcall*, uchar*, Fid*);

static void
initfcall(void)
{
	fcall[Tflush]	= fsysflush;
	fcall[Tversion]	= fsysversion;
	fcall[Tauth]	= fsysauth;
	fcall[Tattach]	= fsysattach;
	fcall[Twalk]	= fsyswalk;
	fcall[Topen]	= fsysopen;
	fcall[Tcreate]	= fsyscreate;
	fcall[Tread]	= fsysread;
	fcall[Twrite]	= fsyswrite;
	fcall[Tclunk]	= fsysclunk;
	fcall[Tremove]= fsysremove;
	fcall[Tstat]	= fsysstat;
	fcall[Twstat]	= fsyswstat;
}

char	Ebadfcall[] =	"bad fcall type";
char	Eperm[] = 	"permission denied";
char	Enomem[] =	"malloc failed for buffer";
char	Enotdir[] =	"not a directory";
char	Enoexist[] =	"plumb file does not exist";
char	Eisdir[] =		"file is a directory";
char	Ebadmsg[] =	"bad plumb message format";
char Enosuchport[] ="no such plumb port";
char Enoport[] =	"couldn't find destination for message";
char	Einuse[] = 	"file already open";

/*
 * Add new port.  A no-op if port already exists or is the null string
 */
void
addport(char *port)
{
	int i;

	if(port == nil)
		return;
	for(i=NQID; i<ndir; i++)
		if(strcmp(port, dir[i].name) == 0)
			return;
	if(i == NDIR){
		fprint(2, "plumb: too many ports; max %d\n", NDIR);
		return;
	}
	ndir++;
	dir[i].name = estrdup(port);
	dir[i].qid = i;
	dir[i].perm = 0400;
	nports++;
	ports = erealloc(ports, nports*sizeof(char*));
	ports[nports-1] = dir[i].name;
}

static ulong
getclock(void)
{
	return time(0);
}

void
startfsys(void)
{
	int p[2];

	fmtinstall('F', fcallfmt);
	clock = getclock();
	if(pipe(p) < 0)
		error("can't create pipe: %r");
	/* 0 will be server end, 1 will be client end */
	srvfd = p[0];
	if(post9pservice(p[1], "plumb", nil) < 0)
		sysfatal("post9pservice plumb: %r");
	close(p[1]);
	proccreate(fsysproc, nil, Stack);
}

static void
fsysproc(void *v)
{
	int n;
	Fcall *t;
	Fid *f;
	uchar *buf;

	USED(v);
	initfcall();
	t = nil;
	for(;;){
		buf = malloc(messagesize);	/* avoid memset of emalloc */
		if(buf == nil)
			error("malloc failed: %r");
		qlock(&readlock);
		n = read9pmsg(srvfd, buf, messagesize);
		if(n <= 0){
			if(n < 0)
				error("i/o error on server channel");
			threadexitsall("unmounted");
		}
		/*
		 * can give false positive (create an extra fsysproc) once in a while,
		 * but no false negatives, so good enough.  once we have one extra
		 * we'll never have more.
		 */
		if(readlock.waiting.head == nil)	/* no other processes waiting to read; start one */
			proccreate(fsysproc, nil, Stack);
		qunlock(&readlock);
		if(t == nil)
			t = emalloc(sizeof(Fcall));
		if(convM2S(buf, n, t) != n)
			error("convert error in convM2S");
		if(debug)
			fprint(2, "<= %F\n", t);
		if(fcall[t->type] == 0)
			fsysrespond(t, buf, Ebadfcall);
		else{
			if(t->type==Tversion || t->type==Tauth)
				f = nil;
			else
				f = newfid(t->fid);
			t = (*fcall[t->type])(t, buf, f);
		}
	}
}

static void
fsysrespond(Fcall *t, uchar *buf, char *err)
{
	int n;

	if(err){
		t->type = Rerror;
		t->ename = err;
	}else
		t->type++;
	if(buf == nil)
		buf = emalloc(messagesize);
	n = convS2M(t, buf, messagesize);
	if(n < 0)
		error("convert error in convS2M");
	if(write(srvfd, buf, n) != n)
		error("write error in respond");
	if(debug)
		fprint(2, "=> %F\n", t);
	free(buf);
}

static
Fid*
newfid(int fid)
{
	Fid *f, *ff, **fh;

	qlock(&queue);
	ff = nil;
	fh = &fids[fid&(Nhash-1)];
	for(f=*fh; f; f=f->next)
		if(f->fid == fid)
			goto Return;
		else if(ff==nil && !f->busy)
			ff = f;
	if(ff){
		ff->fid = fid;
		f = ff;
		goto Return;
	}
	f = emalloc(sizeof *f);
	f->fid = fid;
	f->next = *fh;
	*fh = f;
    Return:
	qunlock(&queue);
	return f;
}

static uint
dostat(Dirtab *dir, uchar *buf, uint nbuf, uint clock)
{
	Dir d;

	d.qid.type = dir->type;
	d.qid.path = dir->qid;
	d.qid.vers = 0;
	d.mode = dir->perm;
	d.length = 0;	/* would be nice to do better */
	d.name = dir->name;
	d.uid = user;
	d.gid = user;
	d.muid = user;
	d.atime = clock;
	d.mtime = clock;
	return convD2M(&d, buf, nbuf);
}

static void
queuesend(Dirtab *d, Plumbmsg *m)
{
	Sendreq *s, *t;
	Fid *f;
	int i;

	s = emalloc(sizeof(Sendreq));
	s->nfid = d->nopen;
	s->nleft = s->nfid;
	s->fid = emalloc(s->nfid*sizeof(Fid*));
	i = 0;
	/* build array of fids open on this channel */
	for(f=d->fopen; f!=nil; f=f->nextopen)
		s->fid[i++] = f;
	s->msg = m;
	s->next = nil;
	/* link to end of queue; drainqueue() searches in sender order so this implements a FIFO */
	for(t=d->sendq; t!=nil; t=t->next)
		if(t->next == nil)
			break;
	if(t == nil)
		d->sendq = s;
	else
		t->next = s;
}

static void
queueread(Dirtab *d, Fcall *t, uchar *buf, Fid *f)
{
	Readreq *r;

	r = emalloc(sizeof(Readreq));
	r->fcall = t;
	r->buf = buf;
	r->fid = f;
	r->next = d->readq;
	d->readq = r;
}

static void
drainqueue(Dirtab *d)
{
	Readreq *r, *nextr, *prevr;
	Sendreq *s, *nexts, *prevs;
	int i, n;

	prevs = nil;
	for(s=d->sendq; s!=nil; s=nexts){
		nexts = s->next;
		for(i=0; i<s->nfid; i++){
			prevr = nil;
			for(r=d->readq; r!=nil; r=nextr){
				nextr = r->next;
				if(r->fid == s->fid[i]){
					/* pack the message if necessary */
					if(s->pack == nil)
						s->pack = plumbpack(s->msg, &s->npack);
					/* exchange the stuff... */
					r->fcall->data = s->pack+r->fid->offset;
					n = s->npack - r->fid->offset;
					if(n > messagesize-IOHDRSZ)
						n = messagesize-IOHDRSZ;
					if(n > r->fcall->count)
						n = r->fcall->count;
					r->fcall->count = n;
					fsysrespond(r->fcall, r->buf, nil);
					r->fid->offset += n;
					if(r->fid->offset >= s->npack){
						/* message transferred; delete this fid from send queue */
						r->fid->offset = 0;
						s->fid[i] = nil;
						s->nleft--;
					}
					/* delete read request from queue */
					if(prevr)
						prevr->next = r->next;
					else
						d->readq = r->next;
					free(r->fcall);
					free(r);
					break;
				}else
					prevr = r;
			}
		}
		/* if no fids left, delete this send from queue */
		if(s->nleft == 0){
			free(s->fid);
			plumbfree(s->msg);
			free(s->pack);
			if(prevs)
				prevs->next = s->next;
			else
				d->sendq = s->next;
			free(s);
		}else
			prevs = s;
	}
}

/* can't flush a send because they are always answered synchronously */
static void
flushqueue(Dirtab *d, int oldtag)
{
	Readreq *r, *prevr;

	prevr = nil;
	for(r=d->readq; r!=nil; r=r->next){
		if(oldtag == r->fcall->tag){
			/* delete read request from queue */
			if(prevr)
				prevr->next = r->next;
			else
				d->readq = r->next;
			free(r->fcall);
			free(r->buf);
			free(r);
			return;
		}
		prevr = r;
	}
}

/* remove messages awaiting delivery to now-closing fid */
static void
removesenders(Dirtab *d, Fid *fid)
{
	Sendreq *s, *nexts, *prevs;
	int i;

	prevs = nil;
	for(s=d->sendq; s!=nil; s=nexts){
		nexts = s->next;
		for(i=0; i<s->nfid; i++)
			if(fid == s->fid[i]){
				/* delete this fid from send queue */
				s->fid[i] = nil;
				s->nleft--;
				break;
			}
		/* if no fids left, delete this send from queue */
		if(s->nleft == 0){
			free(s->fid);
			plumbfree(s->msg);
			free(s->pack);
			if(prevs)
				prevs->next = s->next;
			else
				d->sendq = s->next;
			free(s);
		}else
			prevs = s;
	}
}

static void
hold(Plumbmsg *m, Dirtab *d)
{
	Holdq *h, *q;

	h = emalloc(sizeof(Holdq));
	h->msg = m;
	/* add to end of queue */
	if(d->holdq == nil)
		d->holdq = h;
	else{
		for(q=d->holdq; q->next!=nil; q=q->next)
			;
		q->next = h;
	}
}

static void
queueheld(Dirtab *d)
{
	Holdq *h;

	while(d->holdq != nil){
		h = d->holdq;
		d->holdq = h->next;
		queuesend(d, h->msg);
		/* no need to drain queue because we know no-one is reading yet */
		free(h);
	}
}

static void
dispose(Fcall *t, uchar *buf, Plumbmsg *m, Ruleset *rs, Exec *e)
{
	int i;
	char *err;

	qlock(&queue);
	err = nil;
	if(m->dst==nil || m->dst[0]=='\0'){
		err = Enoport;
		if(rs != nil)
			err = startup(rs, e);
		plumbfree(m);
	}else
		for(i=NQID; i<ndir; i++)
			if(strcmp(m->dst, dir[i].name) == 0){
				if(dir[i].nopen == 0){
					err = startup(rs, e);
					if(e!=nil && e->holdforclient)
						hold(m, &dir[i]);
					else
						plumbfree(m);
				}else{
					queuesend(&dir[i], m);
					drainqueue(&dir[i]);
				}
				break;
			}
	freeexec(e);
	qunlock(&queue);
	fsysrespond(t, buf, err);
	free(t);
}

static Fcall*
fsysversion(Fcall *t, uchar *buf, Fid *fid)
{
	USED(fid);

	if(t->msize < 256){
		fsysrespond(t, buf, "version: message size too small");
		return t;
	}
	if(t->msize < messagesize)
		messagesize = t->msize;
	t->msize = messagesize;
	if(strncmp(t->version, "9P2000", 6) != 0){
		fsysrespond(t, buf, "unrecognized 9P version");
		return t;
	}
	t->version = "9P2000";
	fsysrespond(t, buf, nil);
	return t;
}

static Fcall*
fsysauth(Fcall *t, uchar *buf, Fid *fid)
{
	USED(fid);
	fsysrespond(t, buf, "plumber: authentication not required");
	return t;
}

static Fcall*
fsysattach(Fcall *t, uchar *buf, Fid *f)
{
	Fcall out;

/*
	if(strcmp(t->uname, user) != 0){
		fsysrespond(&out, buf, Eperm);
		return t;
	}
*/
	f->busy = 1;
	f->open = 0;
	f->qid.type = QTDIR;
	f->qid.path = Qdir;
	f->qid.vers = 0;
	f->dir = dir;
	memset(&out, 0, sizeof(Fcall));
	out.type = t->type;
	out.tag = t->tag;
	out.fid = f->fid;
	out.qid = f->qid;
	fsysrespond(&out, buf, nil);
	return t;
}

static Fcall*
fsysflush(Fcall *t, uchar *buf, Fid *fid)
{
	int i;

	USED(fid);
	qlock(&queue);
	for(i=NQID; i<ndir; i++)
		flushqueue(&dir[i], t->oldtag);
	qunlock(&queue);
	fsysrespond(t, buf, nil);
	return t;
}

static Fcall*
fsyswalk(Fcall *t, uchar *buf, Fid *f)
{
	Fcall out;
	Fid *nf;
	ulong path;
	Dirtab *d, *dir;
	Qid q;
	int i;
	uchar type;
	char *err;

	if(f->open){
		fsysrespond(t, buf, "clone of an open fid");
		return t;
	}

	nf = nil;
	if(t->fid  != t->newfid){
		nf = newfid(t->newfid);
		if(nf->busy){
			fsysrespond(t, buf, "clone to a busy fid");
			return t;
		}
		nf->busy = 1;
		nf->open = 0;
		nf->dir = f->dir;
		nf->qid = f->qid;
		f = nf;	/* walk f */
	}

	out.nwqid = 0;
	err = nil;
	dir = f->dir;
	q = f->qid;

	if(t->nwname > 0){
		for(i=0; i<t->nwname; i++){
			if((q.type & QTDIR) == 0){
				err = Enotdir;
				break;
			}
			if(strcmp(t->wname[i], "..") == 0){
				type = QTDIR;
				path = Qdir;
	Accept:
				q.type = type;
				q.vers = 0;
				q.path = path;
				out.wqid[out.nwqid++] = q;
				continue;
			}
			d = dir;
			d++;	/* skip '.' */
			for(; d->name; d++)
				if(strcmp(t->wname[i], d->name) == 0){
					type = d->type;
					path = d->qid;
					dir = d;
					goto Accept;
				}
			err = Enoexist;
			break;
		}
	}

	out.type = t->type;
	out.tag = t->tag;
	if(err!=nil || out.nwqid<t->nwname){
		if(nf)
			nf->busy = 0;
	}else if(out.nwqid == t->nwname){
		f->qid = q;
		f->dir = dir;
	}

	fsysrespond(&out, buf, err);
	return t;
}

static Fcall*
fsysopen(Fcall *t, uchar *buf, Fid *f)
{
	int m, clearrules, mode;

	clearrules = 0;
	if(t->mode & OTRUNC){
		if(f->qid.path != Qrules)
			goto Deny;
		clearrules = 1;
	}
	/* can't truncate anything, so just disregard */
	mode = t->mode & ~(OTRUNC|OCEXEC);
	/* can't execute or remove anything */
	if(mode==OEXEC || (mode&ORCLOSE))
		goto Deny;
	switch(mode){
	default:
		goto Deny;
	case OREAD:
		m = 0400;
		break;
	case OWRITE:
		m = 0200;
		break;
	case ORDWR:
		m = 0600;
		break;
	}
	if(((f->dir->perm&~(DMDIR|DMAPPEND))&m) != m)
		goto Deny;
	if(f->qid.path==Qrules && (mode==OWRITE || mode==ORDWR)){
		lock(&rulesref.lk);
		if(rulesref.ref++ != 0){
			rulesref.ref--;
			unlock(&rulesref.lk);
			fsysrespond(t, buf, Einuse);
			return t;
		}
		unlock(&rulesref.lk);
	}
	if(clearrules){
		writerules(nil, 0);
		rules[0] = nil;
	}
	t->qid = f->qid;
	t->iounit = 0;
	qlock(&queue);
	f->mode = mode;
	f->open = 1;
	f->dir->nopen++;
	f->nextopen = f->dir->fopen;
	f->dir->fopen = f;
	queueheld(f->dir);
	qunlock(&queue);
	fsysrespond(t, buf, nil);
	return t;

    Deny:
	fsysrespond(t, buf, Eperm);
	return t;
}

static Fcall*
fsyscreate(Fcall *t, uchar *buf, Fid *fid)
{
	USED(fid);
	fsysrespond(t, buf, Eperm);
	return t;
}

static Fcall*
fsysreadrules(Fcall *t, uchar *buf)
{
	char *p;
	int n;

	p = printrules();
	n = strlen(p);
	t->data = p;
	if(t->offset >= n)
		t->count = 0;
	else{
		t->data = p+t->offset;
		if(t->offset+t->count > n)
			t->count = n-t->offset;
	}
	fsysrespond(t, buf, nil);
	free(p);
	return t;
}

static Fcall*
fsysread(Fcall *t, uchar *buf, Fid *f)
{
	uchar *b;
	int i, n, o, e;
	uint len;
	Dirtab *d;
	uint clock;

	if(f->qid.path != Qdir){
		if(f->qid.path == Qrules)
			return fsysreadrules(t, buf);
		/* read from port */
		if(f->qid.path < NQID){
			fsysrespond(t, buf, "internal error: unknown read port");
			return t;
		}
		qlock(&queue);
		queueread(f->dir, t, buf, f);
		drainqueue(f->dir);
		qunlock(&queue);
		return nil;
	}
	o = t->offset;
	e = t->offset+t->count;
	clock = getclock();
	b = malloc(messagesize-IOHDRSZ);
	if(b == nil){
		fsysrespond(t, buf, Enomem);
		return t;
	}
	n = 0;
	d = dir;
	d++;	/* first entry is '.' */
	for(i=0; d->name!=nil && i<e; i+=len){
		len = dostat(d, b+n, messagesize-IOHDRSZ-n, clock);
		if(len <= BIT16SZ)
			break;
		if(i >= o)
			n += len;
		d++;
	}
	t->data = (char*)b;
	t->count = n;
	fsysrespond(t, buf, nil);
	free(b);
	return t;
}

static Fcall*
fsyswrite(Fcall *t, uchar *buf, Fid *f)
{
	Plumbmsg *m;
	int i, n;
	long count;
	char *data;
	Exec *e;

	switch((int)f->qid.path){
	case Qdir:
		fsysrespond(t, buf, Eisdir);
		return t;
	case Qrules:
		clock = getclock();
		fsysrespond(t, buf, writerules(t->data, t->count));
		return t;
	case Qsend:
		if(f->offset == 0){
			data = t->data;
			count = t->count;
		}else{
			/* partial message already assembled */
			f->writebuf = erealloc(f->writebuf, f->offset + t->count);
			memmove(f->writebuf+f->offset, t->data, t->count);
			data = f->writebuf;
			count = f->offset+t->count;
		}
		m = plumbunpackpartial(data, count, &n);
		if(m == nil){
			if(n == 0){
				f->offset = 0;
				free(f->writebuf);
				f->writebuf = nil;
				fsysrespond(t, buf, Ebadmsg);
				return t;
			}
			/* can read more... */
			if(f->offset == 0){
				f->writebuf = emalloc(t->count);
				memmove(f->writebuf, t->data, t->count);
			}
			/* else buffer has already been grown */
			f->offset += t->count;
			fsysrespond(t, buf, nil);
			return t;
		}
		/* release partial buffer */
		f->offset = 0;
		free(f->writebuf);
		f->writebuf = nil;
		for(i=0; rules[i]; i++)
			if((e=matchruleset(m, rules[i])) != nil){
				dispose(t, buf, m, rules[i], e);
				return nil;
			}
		if(m->dst != nil){
			dispose(t, buf, m, nil, nil);
			return nil;
		}
		fsysrespond(t, buf, "no matching plumb rule");
		return t;
	}
	fsysrespond(t, buf, "internal error: write to unknown file");
	return t;
}

static Fcall*
fsysstat(Fcall *t, uchar *buf, Fid *f)
{
	t->stat = emalloc(messagesize-IOHDRSZ);
	t->nstat = dostat(f->dir, t->stat, messagesize-IOHDRSZ, clock);
	fsysrespond(t, buf, nil);
	free(t->stat);
	t->stat = nil;
	return t;
}

static Fcall*
fsyswstat(Fcall *t, uchar *buf, Fid *fid)
{
	USED(fid);
	fsysrespond(t, buf, Eperm);
	return t;
}

static Fcall*
fsysremove(Fcall *t, uchar *buf, Fid *fid)
{
	USED(fid);
	fsysrespond(t, buf, Eperm);
	return t;
}

static Fcall*
fsysclunk(Fcall *t, uchar *buf, Fid *f)
{
	Fid *prev, *p;
	Dirtab *d;

	qlock(&queue);
	if(f->open){
		d = f->dir;
		d->nopen--;
		if(d->qid==Qrules && (f->mode==OWRITE || f->mode==ORDWR)){
			/*
			 * just to be sure last rule is parsed; error messages will be lost, though,
			 * unless last write ended with a blank line
			 */
			writerules(nil, 0);
			lock(&rulesref.lk);
			rulesref.ref--;
			unlock(&rulesref.lk);
		}
		prev = nil;
		for(p=d->fopen; p; p=p->nextopen){
			if(p == f){
				if(prev)
					prev->nextopen = f->nextopen;
				else
					d->fopen = f->nextopen;
				removesenders(d, f);
				break;
			}
			prev = p;
		}
	}
	f->busy = 0;
	f->open = 0;
	f->offset = 0;
	if(f->writebuf != nil){
		free(f->writebuf);
		f->writebuf = nil;
	}
	qunlock(&queue);
	fsysrespond(t, buf, nil);
	return t;
}
