#include <u.h>
#include <libc.h>
#include <diskfs.h>
#include <venti.h>

extern void vtlibthread(void);

typedef struct DiskVenti DiskVenti;
struct DiskVenti
{
	Disk disk;
	VtEntry e;
	VtCache *c;
};

extern int nfilereads;

/*
 * This part is like file.c but doesn't require storing the root block
 * in the cache permanently and doesn't care about locking since
 * all the blocks are read-only.  Perhaps at some point this functionality
 * should go into libvac in some form.
 */
static int
vtfileindices(VtEntry *e, u32int bn, int *index)
{
	int i, np;

	memset(index, 0, VtPointerDepth*sizeof(int));

	np = e->psize/VtScoreSize;
	memset(index, 0, sizeof(index));
	for(i=0; bn > 0; i++){
		if(i >= VtPointerDepth){
			werrstr("bad block number %lud", (ulong)bn);
			return -1;
		}
		index[i] = bn % np;
		bn /= np;
	}
	return i;
}

VtBlock *_vtfileblock(VtCache*, VtEntry*, u32int);	/* avoid auto-inline by putting later in file */
static void
diskventiblockput(Block *b)
{
	vtblockput(b->priv);
	free(b);
}

static Block*
diskventiread(Disk *dd, u32int len, u64int offset)
{
	DiskVenti *d = (DiskVenti*)dd;
	VtBlock *vb;
	Block *b;
	int frag;

nfilereads++;
	vb = _vtfileblock(d->c, &d->e, offset/d->e.dsize);
	if(vb == nil)
		return nil;

	b = mallocz(sizeof(Block), 1);
	if(b == nil){
		vtblockput(vb);
		return nil;
	}

	b->priv = vb;
	b->_close = diskventiblockput;
	frag = offset%d->e.dsize;
	b->data = (uchar*)vb->data + frag;
	b->len = d->e.dsize - frag;
	if(b->len > len)
		b->len = len;
	return b;
}

VtBlock*
_vtfileblock(VtCache *c, VtEntry *e, u32int bn)
{
	VtBlock *b, *bb;
	int i, d, index[VtPointerDepth+1], t;
	uchar score[VtScoreSize];

	i = vtfileindices(e, bn, index);
	if(i < 0)
		return nil;
	d = (e->type&VtTypeDepthMask);
	if(i > d){
		werrstr("bad address %d > %d (%x %x)", i, d, e->type, e->flags);
		return nil;
	}

/*fprint(2, "vtread %V\n", e->score); */
	b = vtcacheglobal(c, e->score, e->type);
	for(i=d-1; i>=0 && b; i--){
		t = VtDataType+i;
/*fprint(2, "vtread %V\n", b->data+index[i]*VtScoreSize); */
		memmove(score, b->data+index[i]*VtScoreSize, VtScoreSize);
		vtblockput(b);
		b = vtcacheglobal(c, score, t);
	}
	return b;
}

static void
diskventiclose(Disk *dd)
{
	DiskVenti *d = (DiskVenti*)dd;
	free(d);
}

Disk*
diskopenventi(VtCache *c, uchar score[VtScoreSize])
{
	DiskVenti *d;
	VtEntry e;
	VtRoot root;
	VtBlock *b;

	if((b = vtcacheglobal(c, score, VtRootType)) == nil)
		goto Err;
	if(vtrootunpack(&root, b->data) < 0)
		goto Err;
	if(root.blocksize < 512 || (root.blocksize&(root.blocksize-1))){
		werrstr("bad blocksize %d", root.blocksize);
		goto Err;
	}
	vtblockput(b);

	if((b = vtcacheglobal(c, root.score, VtDirType)) == nil)
		goto Err;
	if(vtentryunpack(&e, b->data, 0) < 0)
		goto Err;
	vtblockput(b);
	b = nil;
	if((e.type&VtTypeBaseMask) != VtDataType){
		werrstr("not a single file");
		goto Err;
	}

	d = mallocz(sizeof(DiskVenti), 1);
	if(d == nil)
		goto Err;

	d->disk._read = diskventiread;
	d->disk._close = diskventiclose;
	d->e = e;
	d->c = c;
	return &d->disk;

Err:
	if(b)
		vtblockput(b);
	return nil;
}

