#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <fcall.h>
#include <plumb.h>
#include "dat.h"
#include "fns.h"

static	int	sfd;

enum
{
	Nhash	= 16,
	DEBUG	= 0
};

static	Fid	*fids[Nhash];

Fid	*newfid(int);

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

Xfid* 	(*fcall[Tmax])(Xfid*, 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 Eperm[] = "permission denied";
char Eexist[] = "file does not exist";
char Enotdir[] = "not a directory";

Dirtab dirtab[]=
{
	{ ".",			QTDIR,	Qdir,		0500|DMDIR },
	{ "acme",		QTDIR,	Qacme,	0500|DMDIR },
	{ "cons",		QTFILE,	Qcons,	0600 },
	{ "consctl",	QTFILE,	Qconsctl,	0000 },
	{ "draw",		QTDIR,	Qdraw,	0000|DMDIR },	/* to suppress graphics progs started in acme */
	{ "editout",	QTFILE,	Qeditout,	0200 },
	{ "index",		QTFILE,	Qindex,	0400 },
	{ "label",		QTFILE,	Qlabel,	0600 },
	{ "new",		QTDIR,	Qnew,	0500|DMDIR },
	{ nil, }
};

Dirtab dirtabw[]=
{
	{ ".",			QTDIR,		Qdir,			0500|DMDIR },
	{ "addr",		QTFILE,		QWaddr,		0600 },
	{ "body",		QTAPPEND,	QWbody,		0600|DMAPPEND },
	{ "ctl",		QTFILE,		QWctl,		0600 },
	{ "data",		QTFILE,		QWdata,		0600 },
	{ "editout",	QTFILE,		QWeditout,	0200 },
	{ "errors",		QTFILE,		QWerrors,		0200 },
	{ "event",		QTFILE,		QWevent,		0600 },
	{ "rdsel",		QTFILE,		QWrdsel,		0400 },
	{ "wrsel",		QTFILE,		QWwrsel,		0200 },
	{ "tag",		QTAPPEND,	QWtag,		0600|DMAPPEND },
	{ "xdata",		QTFILE,		QWxdata,		0600 },
	{ nil, }
};

typedef struct Mnt Mnt;
struct Mnt
{
	QLock	lk;
	int		id;
	Mntdir	*md;
};

Mnt	mnt;

Xfid*	respond(Xfid*, Fcall*, char*);
int		dostat(int, Dirtab*, uchar*, int, uint);
uint	getclock(void);

char	*user = "Wile E. Coyote";
static int closing = 0;
int	messagesize = Maxblock+IOHDRSZ;	/* good start */

void	fsysproc(void *);

void
fsysinit(void)
{
	int p[2];
	char *u;

	initfcall();
	if(pipe(p) < 0)
		error("can't create pipe");
	if(post9pservice(p[0], "acme") < 0)
		error("can't post service");
	sfd = p[1];
	fmtinstall('F', fcallfmt);
	if((u = getuser()) != nil)
		user = estrdup(u);
	proccreate(fsysproc, nil, STACK);
}

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

	threadsetname("fsysproc");

	USED(v);
	x = nil;
	for(;;){
		buf = emalloc(messagesize+UTFmax);	/* overflow for appending partial rune in xfidwrite */
		n = read9pmsg(sfd, buf, messagesize);
		if(n <= 0){
			if(closing)
				break;
			error("i/o error on server channel");
		}
		if(x == nil){
			sendp(cxfidalloc, nil);
			x = recvp(cxfidalloc);
		}
		x->buf = buf;
		if(convM2S(buf, n, &x->fcall) != n)
			error("convert error in convM2S");
		if(DEBUG)
			fprint(2, "%F\n", &x->fcall);
		if(fcall[x->fcall.type] == nil)
			x = respond(x, &t, "bad fcall type");
		else{
			switch(x->fcall.type){
			case Tversion:
			case Tauth:
			case Tflush:
				f = nil;
				break;
			case Tattach:
				f = newfid(x->fcall.fid);
				break;
			default:
				f = newfid(x->fcall.fid);
				if(!f->busy){
					x->f = f;
					x = respond(x, &t, "fid not in use");
					continue;
				}
				break;
			}
			x->f = f;
			x  = (*fcall[x->fcall.type])(x, f);
		}
	}
}

Mntdir*
fsysaddid(Rune *dir, int ndir, Rune **incl, int nincl)
{
	Mntdir *m;
	int id;

	qlock(&mnt.lk);
	id = ++mnt.id;
	m = emalloc(sizeof *m);
	m->id = id;
	m->dir =  dir;
	m->ref = 1;	/* one for Command, one will be incremented in attach */
	m->ndir = ndir;
	m->next = mnt.md;
	m->incl = incl;
	m->nincl = nincl;
	mnt.md = m;
	qunlock(&mnt.lk);
	return m;
}

void
fsysincid(Mntdir *m)
{
	qlock(&mnt.lk);
	m->ref++;
	qunlock(&mnt.lk);
}

void
fsysdelid(Mntdir *idm)
{
	Mntdir *m, *prev;
	int i;
	char buf[64];

	if(idm == nil)
		return;
	qlock(&mnt.lk);
	if(--idm->ref > 0){
		qunlock(&mnt.lk);
		return;
	}
	prev = nil;
	for(m=mnt.md; m; m=m->next){
		if(m == idm){
			if(prev)
				prev->next = m->next;
			else
				mnt.md = m->next;
			for(i=0; i<m->nincl; i++)
				free(m->incl[i]);
			free(m->incl);
			free(m->dir);
			free(m);
			qunlock(&mnt.lk);
			return;
		}
		prev = m;
	}
	qunlock(&mnt.lk);
	sprint(buf, "fsysdelid: can't find id %d\n", idm->id);
	sendp(cerr, estrdup(buf));
}

/*
 * Called only in exec.c:/^run(), from a different FD group
 */
Mntdir*
fsysmount(Rune *dir, int ndir, Rune **incl, int nincl)
{
	return fsysaddid(dir, ndir, incl, nincl);
}

void
fsysclose(void)
{
	closing = 1;
	/*
	 * apparently this is not kosher on openbsd.
	 * perhaps because fsysproc is reading from sfd right now,
	 * the close hangs indefinitely.
	close(sfd);
	 */
}

Xfid*
respond(Xfid *x, Fcall *t, char *err)
{
	int n;

	if(err){
		t->type = Rerror;
		t->ename = err;
	}else
		t->type = x->fcall.type+1;
	t->fid = x->fcall.fid;
	t->tag = x->fcall.tag;
	if(x->buf == nil)
		x->buf = emalloc(messagesize);
	n = convS2M(t, x->buf, messagesize);
	if(n <= 0)
{
fprint(2, "convert error (n=%d, msgsize %d): have %F\n", n, messagesize, &x->fcall);
fprint(2, "\tresponse: %F\n", t);
		error("convert error in convS2M");
}
	if(write(sfd, x->buf, n) != n)
		error("write error in respond");
	free(x->buf);
	x->buf = nil;
	if(DEBUG)
		fprint(2, "r: %F\n", t);
	return x;
}

static
Xfid*
fsysversion(Xfid *x, Fid *f)
{
	Fcall t;

	USED(f);
	if(x->fcall.msize < 256)
		return respond(x, &t, "version: message size too small");
	messagesize = x->fcall.msize;
	t.msize = messagesize;
	if(strncmp(x->fcall.version, "9P2000", 6) != 0)
		return respond(x, &t, "unrecognized 9P version");
	t.version = "9P2000";
	return respond(x, &t, nil);
}

static
Xfid*
fsysauth(Xfid *x, Fid *f)
{
	Fcall t;

	USED(f);
	return respond(x, &t, "acme: authentication not required");
}

static
Xfid*
fsysflush(Xfid *x, Fid *f)
{
	USED(f);
	sendp(x->c, (void*)xfidflush);
	return nil;
}

static
Xfid*
fsysattach(Xfid *x, Fid *f)
{
	Fcall t;
	int id;
	Mntdir *m;
	char buf[128];

	if(strcmp(x->fcall.uname, user) != 0)
		return respond(x, &t, Eperm);
	f->busy = TRUE;
	f->open = FALSE;
	f->qid.path = Qdir;
	f->qid.type = QTDIR;
	f->qid.vers = 0;
	f->dir = dirtab;
	f->nrpart = 0;
	f->w = nil;
	t.qid = f->qid;
	f->mntdir = nil;
	id = atoi(x->fcall.aname);
	qlock(&mnt.lk);
	for(m=mnt.md; m; m=m->next)
		if(m->id == id){
			f->mntdir = m;
			m->ref++;
			break;
		}
	if(m == nil && x->fcall.aname[0]){
		snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
		sendp(cerr, estrdup(buf));
	}
	qunlock(&mnt.lk);
	return respond(x, &t, nil);
}

static
Xfid*
fsyswalk(Xfid *x, Fid *f)
{
	Fcall t;
	int c, i, j, id;
	Qid q;
	uchar type;
	ulong path;
	Fid *nf;
	Dirtab *d, *dir;
	Window *w;
	char *err;

	nf = nil;
	w = nil;
	if(f->open)
		return respond(x, &t, "walk of open file");
	if(x->fcall.fid != x->fcall.newfid){
		nf = newfid(x->fcall.newfid);
		if(nf->busy)
			return respond(x, &t, "newfid already in use");
		nf->busy = TRUE;
		nf->open = FALSE;
		nf->mntdir = f->mntdir;
		if(f->mntdir)
			f->mntdir->ref++;
		nf->dir = f->dir;
		nf->qid = f->qid;
		nf->w = f->w;
		nf->nrpart = 0;	/* not open, so must be zero */
		if(nf->w)
			incref(&nf->w->ref);
		f = nf;	/* walk f */
	}

	t.nwqid = 0;
	err = nil;
	dir = nil;
	id = WIN(f->qid);
	q = f->qid;

	if(x->fcall.nwname > 0){
		for(i=0; i<x->fcall.nwname; i++){
			if((q.type & QTDIR) == 0){
				err = Enotdir;
				break;
			}

			if(strcmp(x->fcall.wname[i], "..") == 0){
				type = QTDIR;
				path = Qdir;
				id = 0;
				if(w){
					winclose(w);
					w = nil;
				}
    Accept:
				if(i == MAXWELEM){
					err = "name too long";
					break;
				}
				q.type = type;
				q.vers = 0;
				q.path = QID(id, path);
				t.wqid[t.nwqid++] = q;
				continue;
			}

			/* is it a numeric name? */
			for(j=0; (c=x->fcall.wname[i][j]); j++)
				if(c<'0' || '9'<c)
					goto Regular;
			/* yes: it's a directory */
			if(w)	/* name has form 27/23; get out before losing w */
				break;
			id = atoi(x->fcall.wname[i]);
			qlock(&row.lk);
			w = lookid(id, FALSE);
			if(w == nil){
				qunlock(&row.lk);
				break;
			}
			incref(&w->ref);	/* we'll drop reference at end if there's an error */
			path = Qdir;
			type = QTDIR;
			qunlock(&row.lk);
			dir = dirtabw;
			goto Accept;
	
    Regular:
/*
			if(FILE(f->qid) == Qacme)	// empty directory
				break;
*/
			if(strcmp(x->fcall.wname[i], "new") == 0){
				if(w)
					error("w set in walk to new");
				sendp(cnewwindow, nil);	/* signal newwindowthread */
				w = recvp(cnewwindow);	/* receive new window */
				incref(&w->ref);
				type = QTDIR;
				path = QID(w->id, Qdir);
				id = w->id;
				dir = dirtabw;
				goto Accept;
			}

			if(id == 0)
				d = dirtab;
			else
				d = dirtabw;
			d++;	/* skip '.' */
			for(; d->name; d++)
				if(strcmp(x->fcall.wname[i], d->name) == 0){
					path = d->qid;
					type = d->type;
					dir = d;
					goto Accept;
				}

			break;	/* file not found */
		}

		if(i==0 && err == nil)
			err = Eexist;
	}

	if(err!=nil || t.nwqid<x->fcall.nwname){
		if(nf){
			nf->busy = FALSE;
			fsysdelid(nf->mntdir);
		}
	}else if(t.nwqid  == x->fcall.nwname){
		if(w){
			f->w = w;
			w = nil;	/* don't drop the reference */
		}
		if(dir)
			f->dir = dir;
		f->qid = q;
	}

	if(w != nil)
		winclose(w);

	return respond(x, &t, err);
}

static
Xfid*
fsysopen(Xfid *x, Fid *f)
{
	Fcall t;
	int m;

	/* can't truncate anything, so just disregard */
	x->fcall.mode &= ~(OTRUNC|OCEXEC);
	/* can't execute or remove anything */
	if(x->fcall.mode==OEXEC || (x->fcall.mode&ORCLOSE))
		goto Deny;
	switch(x->fcall.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;

	sendp(x->c, (void*)xfidopen);
	return nil;

    Deny:
	return respond(x, &t, Eperm);
}

static
Xfid*
fsyscreate(Xfid *x, Fid *f)
{
	Fcall t;

	USED(f);
	return respond(x, &t, Eperm);
}

static
int
idcmp(const void *a, const void *b)
{
	return *(int*)a - *(int*)b;
}

static
Xfid*
fsysread(Xfid *x, Fid *f)
{
	Fcall t;
	uchar *b;
	int i, id, n, o, e, j, k, *ids, nids;
	Dirtab *d, dt;
	Column *c;
	uint clock, len;
	char buf[16];

	if(f->qid.type & QTDIR){
		if(FILE(f->qid) == Qacme){	/* empty dir */
			t.data = nil;
			t.count = 0;
			respond(x, &t, nil);
			return x;
		}
		o = x->fcall.offset;
		e = x->fcall.offset+x->fcall.count;
		clock = getclock();
		b = emalloc(messagesize);
		id = WIN(f->qid);
		n = 0;
		if(id > 0)
			d = dirtabw;
		else
			d = dirtab;
		d++;	/* first entry is '.' */
		for(i=0; d->name!=nil && i<e; i+=len){
			len = dostat(WIN(x->f->qid), d, b+n, x->fcall.count-n, clock);
			if(len <= BIT16SZ)
				break;
			if(i >= o)
				n += len;
			d++;
		}
		if(id == 0){
			qlock(&row.lk);
			nids = 0;
			ids = nil;
			for(j=0; j<row.ncol; j++){
				c = row.col[j];
				for(k=0; k<c->nw; k++){
					ids = realloc(ids, (nids+1)*sizeof(int));
					ids[nids++] = c->w[k]->id;
				}
			}
			qunlock(&row.lk);
			qsort(ids, nids, sizeof ids[0], idcmp);
			j = 0;
			dt.name = buf;
			for(; j<nids && i<e; i+=len){
				k = ids[j];
				sprint(dt.name, "%d", k);
				dt.qid = QID(k, Qdir);
				dt.type = QTDIR;
				dt.perm = DMDIR|0700;
				len = dostat(k, &dt, b+n, x->fcall.count-n, clock);
				if(len == 0)
					break;
				if(i >= o)
					n += len;
				j++;
			}
			free(ids);
		}
		t.data = (char*)b;
		t.count = n;
		respond(x, &t, nil);
		free(b);
		return x;
	}
	sendp(x->c, (void*)xfidread);
	return nil;
}

static
Xfid*
fsyswrite(Xfid *x, Fid *f)
{
	USED(f);
	sendp(x->c, (void*)xfidwrite);
	return nil;
}

static
Xfid*
fsysclunk(Xfid *x, Fid *f)
{
	fsysdelid(f->mntdir);
	sendp(x->c, (void*)xfidclose);
	return nil;
}

static
Xfid*
fsysremove(Xfid *x, Fid *f)
{
	Fcall t;

	USED(f);
	return respond(x, &t, Eperm);
}

static
Xfid*
fsysstat(Xfid *x, Fid *f)
{
	Fcall t;

	t.stat = emalloc(messagesize-IOHDRSZ);
	t.nstat = dostat(WIN(x->f->qid), f->dir, t.stat, messagesize-IOHDRSZ, getclock());
	x = respond(x, &t, nil);
	free(t.stat);
	return x;
}

static
Xfid*
fsyswstat(Xfid *x, Fid *f)
{
	Fcall t;

	USED(f);
	return respond(x, &t, Eperm);
}

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

	ff = nil;
	fh = &fids[fid&(Nhash-1)];
	for(f=*fh; f; f=f->next)
		if(f->fid == fid)
			return f;
		else if(ff==nil && f->busy==FALSE)
			ff = f;
	if(ff){
		ff->fid = fid;
		return ff;
	}
	f = emalloc(sizeof *f);
	f->fid = fid;
	f->next = *fh;
	*fh = f;
	return f;
}

uint
getclock(void)
{
/*
	char buf[32];

	buf[0] = '\0';
	pread(clockfd, buf, sizeof buf, 0);
	return atoi(buf);
*/	
	return time(0);
}

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

	d.qid.path = QID(id, dir->qid);
	d.qid.vers = 0;
	d.qid.type = dir->type;
	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);
}
