#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include "dat.h"
#include "fns.h"

static Xfile*	clean(Xfile*);

#define	FIDMOD	127	/* prime */

static Xdata*	xhead;
static Xfile*	xfiles[FIDMOD];
static Xfile*	freelist;

Xdata*
getxdata(char *name)
{
	int fd;
	Dir *dir;
	Xdata *xf, *fxf;
	int flag;

	if(name[0] == 0)
		name = deffile;
	if(name == 0)
		error(Enofile);
	flag = (access(name, 6) == 0) ? ORDWR : OREAD;
	fd = open(name, flag);
	if(fd < 0)
		error(Enonexist);
	dir = nil;
	if(waserror()){
		close(fd);
		free(dir);
		nexterror();
	}
	if((dir = dirfstat(fd)) == nil)
		error("I/O error");
	if((dir->qid.type & ~QTTMP) != QTFILE)
		error("attach name not a plain file");
	for(fxf=0,xf=xhead; xf; xf=xf->next){
		if(xf->name == 0){
			if(fxf == 0)
				fxf = xf;
			continue;
		}
		if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)
			continue;
		if(xf->type != dir->type || xf->fdev != dir->dev)
			continue;
		xf->ref++;
		chat("incref=%d, \"%s\", dev=%d...", xf->ref, xf->name, xf->dev);
		close(fd);
		poperror();
		free(dir);
		return xf;
	}
	if(fxf==0){
		fxf = ealloc(sizeof(Xfs));
		fxf->next = xhead;
		xhead = fxf;
	}
	chat("alloc \"%s\", dev=%d...", name, fd);
	fxf->ref = 1;
	fxf->name = strcpy(ealloc(strlen(name)+1), name);
	fxf->qid = dir->qid;
	fxf->type = dir->type;
	fxf->fdev = dir->dev;
	fxf->dev = fd;
	free(dir);
	poperror();
	return fxf;
}

static void
putxdata(Xdata *d)
{
	if(d->ref <= 0)
		panic(0, "putxdata");
	d->ref--;
	chat("decref=%d, \"%s\", dev=%d...", d->ref, d->name, d->dev);
	if(d->ref == 0){
		chat("purgebuf...");
		purgebuf(d);
		close(d->dev);
		free(d->name);
		d->name = 0;
	}
}

void
refxfs(Xfs *xf, int delta)
{
	xf->ref += delta;
	if(xf->ref == 0){
		if(xf->d)
			putxdata(xf->d);
		if(xf->ptr)
			free(xf->ptr);
		free(xf);
	}
}

Xfile*
xfile(int fid, int flag)
{
	int k = fid%FIDMOD;
	Xfile **hp=&xfiles[k], *f, *pf;

	for(f=*hp,pf=0; f; pf=f,f=f->next)
		if(f->fid == fid)
			break;
	if(f && pf){
		pf->next = f->next;
		f->next = *hp;
		*hp = f;
	}
	switch(flag){
	default:
		panic(0, "xfile");
	case Asis:
		if(f == 0)
			error("unassigned fid");
		return f;
	case Clean:
		break;
	case Clunk:
		if(f){
			*hp = f->next;
			clean(f);
			f->next = freelist;
			freelist = f;
		}
		return 0;
	}
	if(f)
		return clean(f);
	if(f = freelist)	/* assign = */
		freelist = f->next;
	else
		f = ealloc(sizeof(Xfile));
	f->next = *hp;
	*hp = f;
	f->xf = 0;
	f->fid = fid;
	f->flags = 0;
	f->qid = (Qid){0,0,0};
	f->len = 0;
	f->ptr = 0;
	return f;
}

static Xfile *
clean(Xfile *f)
{
	if(f->xf){
		refxfs(f->xf, -1);
		f->xf = 0;
	}
	if(f->len){
		free(f->ptr);
		f->len = 0;
	}
	f->ptr = 0;
	f->flags = 0;
	f->qid = (Qid){0,0,0};
	return f;
}

