#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*) =
{
	[Tflush]	= fsysflush,
	[Tversion]	= fsysversion,
	[Tauth]	= fsysauth,
	[Tattach]	= fsysattach,
	[Twalk]	= fsyswalk,
	[Topen]	= fsysopen,
	[Tcreate]	= fsyscreate,
	[Tread]	= fsysread,
	[Twrite]	= fsyswrite,
	[Tclunk]	= fsysclunk,
	[Tremove]= fsysremove,
	[Tstat]	= fsysstat,
	[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 },
	{ "event",		QTFILE,		QWevent,		0600 },
	{ "rdsel",		QTFILE,		QWrdsel,		0400 },
	{ "wrsel",		QTFILE,		QWwrsel,		0200 },
	{ "tag",		QTAPPEND,	QWtag,		0600|DMAPPEND },
	{ 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];
	int n, fd;
	char buf[256], *u;

	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;

	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{
			if(x->fcall.type==Tversion || x->fcall.type==Tauth)
				f = nil;
			else
				f = newfid(x->fcall.fid);
			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
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;
	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)
		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)
{
	USED(f);
	return respond(x, nil, "acme: authentication not required");
}

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

static
Xfid*
fsysattach(Xfid *x, Fid *f)
{
	Fcall t;
	int id;
	Mntdir *m;

	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)
		sendp(cerr, estrdup("unknown id in attach"));
	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, 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, xfidread);
	return nil;
}

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

static
Xfid*
fsysclunk(Xfid *x, Fid *f)
{
	fsysdelid(f->mntdir);
	sendp(x->c, 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);
}
