/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
/* See COPYRIGHT */

#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <9pclient.h>
#include <thread.h>
#include "fsimpl.h"

static int _fssend(Mux*, void*);
static void *_fsrecv(Mux*);
static int _fsgettag(Mux*, void*);
static int _fssettag(Mux*, void*, uint);

enum
{
	CFidchunk = 32
};

CFsys*
fsinit(int fd)
{
	CFsys *fs;

	fmtinstall('F', fcallfmt);
	fmtinstall('D', dirfmt);
	fmtinstall('M', dirmodefmt);

	fs = mallocz(sizeof(CFsys), 1);
	if(fs == nil)
		return nil;
	fs->fd = fd;
	fs->ref = 1;
	fs->mux.aux = fs;
	fs->mux.mintag = 0;
	fs->mux.maxtag = 256;
	fs->mux.send = _fssend;
	fs->mux.recv = _fsrecv;
	fs->mux.gettag = _fsgettag;
	fs->mux.settag = _fssettag;
	fs->iorecv = ioproc();
	fs->iosend = ioproc();
	muxinit(&fs->mux);
	return fs;
}

CFid*
fsroot(CFsys *fs)
{
	/* N.B. no incref */
	return fs->root;
}

CFsys*
fsmount(int fd, char *aname)
{
	int n;
	CFsys *fs;
	CFid *fid;

	fs = fsinit(fd);
	if(fs == nil)
		return nil;
	strcpy(fs->version, "9P2000");
	if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){
	Error:
		fs->fd = -1;
		fsunmount(fs);
		return nil;
	}
	fs->msize = n;

	if((fid = fsattach(fs, nil, getuser(), aname)) == nil)
		goto Error;
	fssetroot(fs, fid);
	return fs;
}

void
fsunmount(CFsys *fs)
{
	fsclose(fs->root);
	fs->root = nil;
	_fsdecref(fs);
}

void
_fsdecref(CFsys *fs)
{
	CFid *f, **l, *next;

	qlock(&fs->lk);
	--fs->ref;
	//fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
	if(fs->ref == 0){
		if(fs->fd >= 0)
			close(fs->fd);
		/* trim the list down to just the first in each chunk */
		for(l=&fs->freefid; *l; ){
			if((*l)->fid%CFidchunk == 0)
				l = &(*l)->next;
			else
				*l = (*l)->next;
		}
		/* now free the list */
		for(f=fs->freefid; f; f=next){
			next = f->next;
			free(f);
		}
		closeioproc(fs->iorecv);
		closeioproc(fs->iosend);
		free(fs);
		return;
	}
	qunlock(&fs->lk);
}

int
fsversion(CFsys *fs, int msize, char *version, int nversion)
{
	void *freep;
	int r, oldmintag, oldmaxtag;
	Fcall tx, rx;

	tx.tag = 0;
	tx.type = Tversion;
	tx.version = version;
	tx.msize = msize;

	/*
	 * bit of a clumsy hack -- force libmux to use NOTAG as tag.
	 * version can only be sent when there are no other messages
	 * outstanding on the wire, so this is more reasonable than it looks.
	 */
	oldmintag = fs->mux.mintag;
	oldmaxtag = fs->mux.maxtag;
	fs->mux.mintag = NOTAG;
	fs->mux.maxtag = NOTAG+1;
	r = _fsrpc(fs, &tx, &rx, &freep);
	fs->mux.mintag = oldmintag;
	fs->mux.maxtag = oldmaxtag;
	if(r < 0)
		return -1;

	strecpy(version, version+nversion, rx.version);
	free(freep);
	return rx.msize;
}

CFid*
fsattach(CFsys *fs, CFid *afid, char *user, char *aname)
{
	Fcall tx, rx;
	CFid *fid;

	if(aname == nil)
		aname = "";

	if((fid = _fsgetfid(fs)) == nil)
		return nil;

	tx.tag = 0;
	tx.type = Tattach;
	tx.afid = afid ? afid->fid : NOFID;
	tx.fid = fid->fid;
	tx.uname = user;
	tx.aname = aname;

	if(_fsrpc(fs, &tx, &rx, 0) < 0){
		_fsputfid(fid);
		return nil;
	}
	fid->qid = rx.qid;
	return fid;
}

void
fssetroot(CFsys *fs, CFid *fid)
{
	if(fs->root)
		_fsputfid(fs->root);
	fs->root = fid;
}

int
_fsrpc(CFsys *fs, Fcall *tx, Fcall *rx, void **freep)
{
	int n, nn;
	void *tpkt, *rpkt;

	n = sizeS2M(tx);
	tpkt = malloc(n);
	if(freep)
		*freep = nil;
	if(tpkt == nil)
		return -1;
	//fprint(2, "<- %F\n", tx);
	nn = convS2M(tx, tpkt, n);
	if(nn != n){
		free(tpkt);
		werrstr("libfs: sizeS2M convS2M mismatch");
		fprint(2, "%r\n");
		return -1;
	}
	rpkt = muxrpc(&fs->mux, tpkt);
	free(tpkt);
	if(rpkt == nil)
		return -1;
	n = GBIT32((uchar*)rpkt);
	nn = convM2S(rpkt, n, rx);
	if(nn != n){
		free(rpkt);
		werrstr("libfs: convM2S packet size mismatch %d %d", n, nn);
		fprint(2, "%r\n");
		return -1;
	}
	//fprint(2, "-> %F\n", rx);
	if(rx->type == Rerror){
		werrstr("%s", rx->ename);
		free(rpkt);
		return -1;
	}
	if(rx->type != tx->type+1){
		werrstr("packet type mismatch -- tx %d rx %d",
			tx->type, rx->type);
		free(rpkt);
		return -1;
	}
	if(freep)
		*freep = rpkt;
	else
		free(rpkt);
	return 0;
}

CFid*
_fsgetfid(CFsys *fs)
{
	int i;
	CFid *f;

	qlock(&fs->lk);
	if(fs->freefid == nil){
		f = mallocz(sizeof(CFid)*CFidchunk, 1);
		if(f == nil){
			qunlock(&fs->lk);
			return nil;
		}
		for(i=0; i<CFidchunk; i++){
			f[i].fid = fs->nextfid++;
			f[i].next = &f[i+1];
			f[i].fs = fs;
		}
		f[i-1].next = nil;
		fs->freefid = f;
	}
	f = fs->freefid;
	fs->freefid = f->next;
	fs->ref++;
	qunlock(&fs->lk);
	return f;
}

void
_fsputfid(CFid *f)
{
	CFsys *fs;

	fs = f->fs;
	qlock(&fs->lk);
	f->next = fs->freefid;
	fs->freefid = f;
	qunlock(&fs->lk);
	_fsdecref(fs);
}

static int
_fsgettag(Mux *mux, void *pkt)
{
	return GBIT16((uchar*)pkt+5);
}

static int
_fssettag(Mux *mux, void *pkt, uint tag)
{
	PBIT16((uchar*)pkt+5, tag);
	return 0;
}

static int
_fssend(Mux *mux, void *pkt)
{
	CFsys *fs;

	fs = mux->aux;
	return iowrite(fs->iosend, fs->fd, pkt, GBIT32((uchar*)pkt));
}

static void*
_fsrecv(Mux *mux)
{
	uchar *pkt;
	uchar buf[4];
	int n, nfd;
	CFsys *fs;

	fs = mux->aux;
	n = ioreadn(fs->iorecv, fs->fd, buf, 4);
	if(n != 4)
		return nil;
	n = GBIT32(buf);
	pkt = malloc(n+4);
	if(pkt == nil){
		fprint(2, "libfs out of memory reading 9p packet; here comes trouble\n");
		return nil;
	}
	PBIT32(pkt, n);
	if(ioreadn(fs->iorecv, fs->fd, pkt+4, n-4) != n-4){
		free(pkt);
		return nil;
	}
	if(pkt[4] == Ropenfd){
		if((nfd=iorecvfd(fs->iorecv, fs->fd)) < 0){
			fprint(2, "recv fd error: %r\n");
			free(pkt);
			return nil;
		}
		PBIT32(pkt+n-4, nfd);
	}
	return pkt;
}
