#include <u.h>
#include <libc.h>
#include <thread.h>
#include <sunrpc.h>
#include <nfs3.h>
#include <diskfs.h>
#include "ext2.h"

#define debug 1

static int ext2sync(Fsys*);
static void ext2close(Fsys*);
static Block* ext2blockread(Fsys*, u64int);

static Nfs3Status ext2root(Fsys*, Nfs3Handle*);
static Nfs3Status ext2getattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
static Nfs3Status ext2lookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
static Nfs3Status ext2readfile(Fsys*, SunAuthUnix *au, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
static Nfs3Status ext2readlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link);
static Nfs3Status ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
static Nfs3Status ext2access(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr);

Fsys*
fsysopenext2(Disk *disk)
{
	Ext2 *fs;
	Fsys *fsys;

	fsys = emalloc(sizeof(Fsys));
	fs = emalloc(sizeof(Ext2));
	fs->disk = disk;
	fsys->priv = fs;
	fs->fsys = fsys;
	fsys->type = "ext2";
	fsys->_readblock = ext2blockread;
	fsys->_sync = ext2sync;
	fsys->_root = ext2root;
	fsys->_getattr = ext2getattr;
	fsys->_access = ext2access;
	fsys->_lookup = ext2lookup;
	fsys->_readfile = ext2readfile;
	fsys->_readlink = ext2readlink;
	fsys->_readdir = ext2readdir;

	if(ext2sync(fsys) < 0)
		goto error;

	return fsys;

error:
	ext2close(fsys);
	return nil;
}

static void
ext2close(Fsys *fsys)
{
	Ext2 *fs;

	fs = fsys->priv;
	free(fs);
	free(fsys);
}

static Group*
ext2group(Ext2 *fs, u32int i, Block **pb)
{
	Block *b;
	u64int addr;
	Group *g;

	if(i >= fs->ngroup)
		return nil;

	addr = fs->groupaddr + i/fs->descperblock;
	b = diskread(fs->disk, fs->blocksize, addr*fs->blocksize);
	if(b == nil)
		return nil;
	g = (Group*)(b->data+i%fs->descperblock*GroupSize);
	*pb = b;
	return g;
}

static Block*
ext2blockread(Fsys *fsys, u64int vbno)
{
	Block *bitb;
	Group *g;
	Block *gb;
	uchar *bits;
	u32int bno, boff;
	Ext2 *fs;

	fs = fsys->priv;
	if(vbno >= fs->nblock)
		return nil;
	bno = vbno;
	if(bno != vbno)
		return nil;

/*	
	if(bno < fs->firstblock)
		return diskread(fs->disk, fs->blocksize, (u64int)bno*fs->blocksize);
*/
	if(bno < fs->firstblock)
		return nil;

	bno -= fs->firstblock;
	if((g = ext2group(fs, bno/fs->blockspergroup, &gb)) == nil){
		if(debug)
			fprint(2, "loading group: %r...");
		return nil;
	}
//	if(debug)
//		fprint(2, "group %d bitblock=%d...", bno/fs->blockspergroup, g->bitblock);

	if((bitb = diskread(fs->disk, fs->blocksize, (u64int)g->bitblock*fs->blocksize)) == nil){
		if(debug)
			fprint(2, "loading bitblock: %r...");
		blockput(gb);
		return nil;
	}
	bits = bitb->data;
	boff = bno%fs->blockspergroup;
	if((bits[boff>>3] & (1<<(boff&7))) == 0){
		if(debug)
			fprint(2, "block %d not allocated...", bno);
		blockput(bitb);
		blockput(gb);
		return nil;
	}

	bno += fs->firstblock;
	return diskread(fs->disk, fs->blocksize, (u64int)bno*fs->blocksize);
}

static Block*
ext2datablock(Ext2 *fs, u32int bno, int size)
{
	USED(size);
	return ext2blockread(fs->fsys, bno+fs->firstblock);
}

static Block*
ext2fileblock(Ext2 *fs, Inode *ino, u32int bno, int size)
{
	int ppb;
	Block *b;
	u32int *a;
	u32int obno;

	obno = bno;
	if(bno < NDIRBLOCKS){
		if(debug)
			fprint(2, "fileblock %d -> %d...", 
				bno, ino->block[bno]);
		return ext2datablock(fs, ino->block[bno], size);
	}
	bno -= NDIRBLOCKS;
	ppb = fs->blocksize/4;

	/* one indirect */
	if(bno < ppb){
		b = ext2datablock(fs, ino->block[INDBLOCK], fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[bno%ppb];
		blockput(b);
		return ext2datablock(fs, bno, size);
	}
	bno -= ppb;

	/* one double indirect */
	if(bno < ppb*ppb){
		b = ext2datablock(fs, ino->block[DINDBLOCK], fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[(bno/ppb)%ppb];
		blockput(b);
		b = ext2datablock(fs, bno, fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[bno%ppb];
		blockput(b);
		return ext2datablock(fs, bno, size);
	}
	bno -= ppb*ppb;

	/* one triple indirect */
	if(bno < ppb*ppb*ppb){
		b = ext2datablock(fs, ino->block[TINDBLOCK], fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[(bno/(ppb*ppb))%ppb];
		blockput(b);
		b = ext2datablock(fs, bno, fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[(bno/ppb)%ppb];
		blockput(b);
		b = ext2datablock(fs, bno, fs->blocksize);
		if(b == nil)
			return nil;
		a = (u32int*)b->data;
		bno = a[bno%ppb];
		blockput(b);
		return ext2datablock(fs, bno, size);
	}

	fprint(2, "ext2fileblock %ud: too big\n", obno);
	return nil;
}

static int
checksuper(Super *super)
{
	if(super->magic != SUPERMAGIC){
		werrstr("bad magic 0x%ux wanted 0x%ux", super->magic, SUPERMAGIC);
		return -1;
	}
	return 0;
}

static int
ext2sync(Fsys *fsys)
{
	int i;
	Group *g;
	Block *b;
	Super *super;
	Ext2 *fs;
	Disk *disk;

	fs = fsys->priv;
	disk = fs->disk;
	if((b = diskread(disk, SBSIZE, SBOFF)) == nil)
		goto error;
	super = (Super*)b->data;
	if(checksuper(super) < 0)
		goto error;
	fs->blocksize = MINBLOCKSIZE<<super->logblocksize;
	fs->nblock = super->nblock;
	fs->ngroup = (super->nblock+super->blockspergroup-1)
		/ super->blockspergroup;
	fs->inospergroup = super->inospergroup;
	fs->blockspergroup = super->blockspergroup;
	fs->inosperblock = fs->blocksize / InodeSize;
	if(fs->blocksize == SBOFF)
		fs->groupaddr = 2;
	else
		fs->groupaddr = 1;
	fs->descperblock = fs->blocksize / GroupSize;
	fs->firstblock = super->firstdatablock;
	blockput(b);

	fsys->blocksize = fs->blocksize;
	fsys->nblock = fs->nblock;
	fprint(2, "ext2 %d %d-byte blocks, first data block %d, %d groups of %d\n",
		fs->nblock, fs->blocksize, fs->firstblock, fs->ngroup, fs->blockspergroup);

	if(0){
		for(i=0; i<fs->ngroup; i++)
			if((g = ext2group(fs, i, &b)) != nil){
				fprint(2, "grp %d: bitblock=%d\n", i, g->bitblock);
				blockput(b);
			}
	}
	return 0;

error:
	blockput(b);
	return -1;
}

static void
mkhandle(Nfs3Handle *h, u64int ino)
{
	h->h[0] = ino>>24;
	h->h[1] = ino>>16;
	h->h[2] = ino>>8;
	h->h[3] = ino;
	h->len = 4;
}

static u32int
byte2u32(uchar *p)
{
	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}

static Nfs3Status
handle2ino(Ext2 *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
{
	int i;
	uint ioff;
	u32int inum;
	u32int addr;
	Block *gb, *b;
	Group *g;

	if(h->len != 4)
		return Nfs3ErrBadHandle;
	inum = byte2u32(h->h);
	if(pinum)
		*pinum = inum;
	i = (inum-1) / fs->inospergroup;
	if(i >= fs->ngroup)
		return Nfs3ErrBadHandle;
	ioff = (inum-1) % fs->inospergroup;
	if((g = ext2group(fs, i, &gb)) == nil)
		return Nfs3ErrIo;
	addr = g->inodeaddr + ioff/fs->inosperblock;
	blockput(gb);
	if((b = diskread(fs->disk, fs->blocksize, (u64int)addr*fs->blocksize)) == nil)
		return Nfs3ErrIo;
	*ino = ((Inode*)b->data)[ioff%fs->inosperblock];
	blockput(b);
	return Nfs3Ok;
}

static Nfs3Status
ext2root(Fsys *fsys, Nfs3Handle *h)
{
	USED(fsys);
	mkhandle(h, ROOTINODE);
	return Nfs3Ok;
}

static Nfs3Status
ino2attr(Ext2 *fs, Inode *ino, u32int inum, Nfs3Attr *attr)
{
	u32int rdev;

	attr->type = -1;
	switch(ino->mode&IFMT){
	case IFIFO:
		attr->type = Nfs3FileFifo;
		break;
	case IFCHR:
		attr->type = Nfs3FileChar;
		break;
	case IFDIR:
		attr->type = Nfs3FileDir;
		break;
	case IFBLK:
		attr->type = Nfs3FileBlock;
		break;
	case IFREG:
		attr->type = Nfs3FileReg;
		break;
	case IFLNK:
		attr->type = Nfs3FileSymlink;
		break;
	case IFSOCK:
		attr->type = Nfs3FileSocket;
		break;
	case IFWHT:
	default:
		return Nfs3ErrBadHandle;
	}

	attr->mode = ino->mode&07777;
	attr->nlink = ino->nlink;
	attr->uid = ino->uid;
	attr->gid = ino->gid;
	attr->size = ino->size;
	attr->used = ino->nblock*fs->blocksize;
	if(attr->type==Nfs3FileBlock || attr->type==Nfs3FileChar){
		rdev = ino->block[0];
		attr->major = (rdev>>8)&0xFF;
		attr->minor = rdev & 0xFFFF00FF;
	}else{
		attr->major = 0;
		attr->minor = 0;
	}
	attr->fsid = 0;
	attr->fileid = inum;
	attr->atime.sec = ino->atime;
	attr->atime.nsec = 0;
	attr->mtime.sec = ino->mtime;
	attr->mtime.nsec = 0;
	attr->ctime.sec = ino->ctime;
	attr->ctime.nsec = 0;
	return Nfs3Ok;
}

static int
ingroup(SunAuthUnix *au, uint gid)
{
	int i;

	for(i=0; i<au->ng; i++)
		if(au->g[i] == gid)
			return 1;
	return 0;
}

static Nfs3Status
inoperm(Inode *ino, SunAuthUnix *au, int need)
{
	int have;

	if(allowall)
		return Nfs3Ok;

	have = ino->mode&0777;
	if(ino->uid == au->uid)
		have >>= 6;
	else if(ino->gid == au->gid || ingroup(au, ino->gid))
		have >>= 3;

	if((have&need) != need)
		return Nfs3ErrNotOwner;	/* really EPERM */
	return Nfs3Ok;
}

static Nfs3Status
ext2getattr(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
{
	Inode ino;
	u32int inum;
	Ext2 *fs;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
		return ok;

	USED(au);	/* anyone can getattr */
	return ino2attr(fs, &ino, inum, attr);
}

static Nfs3Status
ext2access(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
{
	int have;
	Inode ino;
	u32int inum;
	Ext2 *fs;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
		return ok;

	have = ino.mode&0777;
	if(ino.uid == au->uid)
		have >>= 6;
	else if(ino.gid == au->gid || ingroup(au, ino.gid))
		have >>= 3;

	*got = 0;
	if((want&Nfs3AccessRead) && (have&AREAD))
		*got |= Nfs3AccessRead;
	if((want&Nfs3AccessLookup) && (ino.mode&IFMT)==IFDIR && (have&AEXEC))
		*got |= Nfs3AccessLookup;
	if((want&Nfs3AccessExecute) && (ino.mode&IFMT)!=IFDIR && (have&AEXEC))
		*got |= Nfs3AccessExecute;

	return ino2attr(fs, &ino, inum, attr);
}

static Nfs3Status
ext2lookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
{
	u32int nblock;
	u32int i;
	uchar *p, *ep;
	Dirent *de;
	Inode ino;
	Block *b;
	Ext2 *fs;
	Nfs3Status ok;
	int len, want;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ino.mode&IFMT) != IFDIR)
		return Nfs3ErrNotDir;

	if((ok = inoperm(&ino, au, AEXEC)) != Nfs3Ok)
		return ok;

	len = strlen(name);
	nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
	if(debug) fprint(2, "%d blocks in dir...", nblock);
	for(i=0; i<nblock; i++){
		if(i==nblock-1)
			want = ino.size % fs->blocksize;
		else
			want = fs->blocksize;
		b = ext2fileblock(fs, &ino, i, want);
		if(b == nil){
			if(debug) fprint(2, "empty block...");
			continue;
		}
		p = b->data;
		ep = p+b->len;
		while(p < ep){
			de = (Dirent*)p;
			if(de->reclen == 0){
				if(debug)
					fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
				break;
			}
			p += de->reclen;
			if(p > ep){
				if(debug)
					fprint(2, "bad len %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->ino == 0)
				continue;
			if(4+2+2+de->namlen > de->reclen){
				if(debug)
					fprint(2, "bad namelen %d at offset %d of %d\n", de->namlen, (int)(p-b->data), b->len);
				break;
			}
			if(de->namlen == len && memcmp(de->name, name, len) == 0){
				mkhandle(nh, de->ino);
				blockput(b);
				return Nfs3Ok;
			}
		}
		blockput(b);
	}
	return Nfs3ErrNoEnt;
}

static Nfs3Status
ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
{
	u32int nblock;
	u32int i;
	int off, done;
	uchar *data, *dp, *dep, *p, *ep, *ndp;
	Dirent *de;
	Inode ino;
	Block *b;
	Ext2 *fs;
	Nfs3Status ok;
	Nfs3Entry e;
	int want;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ino.mode&IFMT) != IFDIR)
		return Nfs3ErrNotDir;

	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(cookie >= ino.size){
		*pcount = 0;
		*pdata = 0;
		return Nfs3Ok;
	}

	dp = malloc(count);
	data = dp;
	if(dp == nil)
		return Nfs3ErrNoMem;
	dep = dp+count;
	*peof = 0;
	nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
	i = cookie/fs->blocksize;
	off = cookie%fs->blocksize;
	done = 0;
	for(; i<nblock && !done; i++){
		if(i==nblock-1)
			want = ino.size % fs->blocksize;
		else
			want = fs->blocksize;
		b = ext2fileblock(fs, &ino, i, want);
		if(b == nil)
			continue;
		p = b->data;
		ep = p+b->len;
		memset(&e, 0, sizeof e);
		while(p < ep){
			de = (Dirent*)p;
			if(de->reclen == 0){
				if(debug) fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
				break;
			}
			p += de->reclen;
			if(p > ep){
				if(debug) fprint(2, "reclen %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->ino == 0){
				if(debug) fprint(2, "zero inode\n");
				continue;
			}
			if(4+2+2+de->namlen > de->reclen){
				if(debug) fprint(2, "bad namlen %d reclen %d at offset %d of %d\n", de->namlen, de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->name[de->namlen] != 0){
				if(debug) fprint(2, "bad name %d %.*s\n", de->namlen, de->namlen, de->name);
				continue;
			}
			if(debug) print("%s/%d ", de->name, (int)de->ino);
			if((uchar*)de - b->data < off)
				continue;
			e.fileid = de->ino;
			e.name = de->name;
			e.cookie = (u64int)i*fs->blocksize + (p - b->data);
			if(nfs3entrypack(dp, dep, &ndp, &e) < 0){
				done = 1;
				break;
			}
			dp = ndp;
		}
		off = 0;
		blockput(b);
	}
	if(i==nblock)
		*peof = 1;

	*pcount = dp - data;
	*pdata = data;
	return Nfs3Ok;
}

static Nfs3Status
ext2readfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
	u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
{
	uchar *data;
	Block *b;
	Ext2 *fs;
	int off, want, fragcount;
	Inode ino;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(offset >= ino.size){
		*pdata = 0;
		*pcount = 0;
		*peof = 1;
		return Nfs3Ok;
	}
	if(offset+count > ino.size)
		count = ino.size-offset;
	if(offset/fs->blocksize != (offset+count-1)/fs->blocksize)
		count = fs->blocksize - offset%fs->blocksize;

	data = malloc(count);
	if(data == nil)
		return Nfs3ErrNoMem;

	want = offset%fs->blocksize+count;
	if(want%fs->blocksize)
		want += fs->blocksize - want%fs->blocksize;

	b = ext2fileblock(fs, &ino, offset/fs->blocksize, want);
	if(b == nil){
		/* BUG: distinguish sparse file from I/O error */
		memset(data, 0, count);
	}else{
		off = offset%fs->blocksize;
		fragcount = count;	/* need signed variable */
		if(off+fragcount > b->len){
			fragcount = b->len - off;
			if(fragcount < 0)
				fragcount = 0;
		}
		if(fragcount > 0)
			memmove(data, b->data+off, fragcount);
		count = fragcount;
		blockput(b);
	}
	*peof = (offset+count == ino.size);
	*pcount = count;
	*pdata = data;
	return Nfs3Ok;
}

static Nfs3Status
ext2readlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
{
	Ext2 *fs;
	Nfs3Status ok;
	int len;
	Inode ino;
	Block *b;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;
	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(ino.size > 1024)
		return Nfs3ErrIo;
	len = ino.size;

	if(ino.nblock != 0){
		/* BUG: assumes symlink fits in one block */
		b = ext2fileblock(fs, &ino, 0, len);
		if(b == nil)
			return Nfs3ErrIo;
		if(memchr(b->data, 0, len) != nil){
			blockput(b);
			return Nfs3ErrIo;
		}
		*link = malloc(len+1);
		if(*link == 0){
			blockput(b);
			return Nfs3ErrNoMem;
		}
		memmove(*link, b->data, len);
		(*link)[len] = 0;
		blockput(b);
		return Nfs3Ok;
	}

	if(len > sizeof ino.block)
		return Nfs3ErrIo;

	*link = malloc(len+1);
	if(*link == 0)
		return Nfs3ErrNoMem;
	memmove(*link, ino.block, ino.size);
	(*link)[len] = 0;
	return Nfs3Ok;
}

