#include <u.h>
#include <libc.h>
#include <bio.h>
#include <thread.h>
#include <venti.h>
#include <sunrpc.h>
#include <nfs3.h>
#include <diskfs.h>

uchar *buf;
uint bufsize;
Nfs3Handle cwd, root;
Biobuf bin, bout;
char pwd[1000];
Fsys *fsys;
SunAuthUnix *auth;
VtConn *z;
VtCache *c;
Disk *disk;

char *cmdhelp(int, char**);
char *cmdcd(int, char**);
char *cmdpwd(int, char**);
char *cmdls(int, char**);
char *cmdcp(int, char**);
char *cmdblock(int, char**);
char *cmddisk(int, char**);

typedef struct Cmd Cmd;
struct Cmd
{
	char *s;
	char *(*fn)(int, char**);
	char *help;
};

Cmd cmdtab[] = 
{
	"cd", cmdcd, "cd dir - change directory",
	"ls", cmdls, "ls [-d] path... - list file",
	"pwd", cmdpwd, "pwd - print working directory",
	"help", cmdhelp, "help - print usage summaries",
	"block", cmdblock, "block path offset - print disk offset of path's byte offset",
	"disk", cmddisk, "disk offset count - dump disk contents",
};

char*
ebuf(void)
{
	static char buf[ERRMAX];
	
	rerrstr(buf, sizeof buf);
	return buf;
}

char*
walk(char *path, Nfs3Handle *ph)
{
	char *p, *q;
	Nfs3Handle h;
	Nfs3Status ok;
	
	if(path[0] == '/')
		h = root;
	else
		h = cwd;
	for(p=path; *p; p=q){
		q = strchr(p, '/');
		if(q == nil)
			q = p+strlen(p);
		else
			*q++ = 0;
		if(*p == 0)
			continue;
		if((ok = fsyslookup(fsys, auth, &h, p, &h)) != Nfs3Ok){
			nfs3errstr(ok);
			return ebuf();
		}
	}
	*ph = h;
	return nil;
}

char*
cmdhelp(int argc, char **argv)
{
	int i;
	
	for(i=0; i<nelem(cmdtab); i++)
		print("%s\n", cmdtab[i].help);
	return nil;
}

char*
cmdcd(int argc, char **argv)
{
	char *err;
	Nfs3Attr attr;
	Nfs3Status ok;
	Nfs3Handle h;
	
	if(argc != 2)
		return "usage: cd dir";
	
	if((err = walk(argv[1], &h)) != nil)
		return err;
	if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
		nfs3errstr(ok);
		fprint(2, "%s: %r\n");
		return nil;
	}
	if(attr.type != Nfs3FileDir)
		return "not a directory";
	if(argv[1][0] == '/')
		pwd[0] = 0;
	strcat(pwd, "/");
	strcat(pwd, argv[1]);
	cleanname(pwd);
	cwd = h;
	print("%s\n", pwd);
	return nil;
}

char*
cmdpwd(int argc, char **argv)
{
	if(argc != 1)
		return "usage: pwd";

	print("%s\n", pwd);
	return nil;
}

/*
 * XXX maybe make a list of these in memory and then print them nicer
 */
void
ls(char *dir, char *elem, Nfs3Attr *attr)
{
	char c;
	
	c = ' ';	/* use attr->type */
	Bprint(&bout, "%s%s%s", dir ? dir : "", dir && elem ? "/" : "", elem ? elem : "");
	Bprint(&bout, " %c%luo %1d %4d %4d", c, attr->mode, attr->nlink, attr->uid, attr->gid);
	Bprint(&bout, " %11,lld %11,lld %4d.%4d %#11,llux %#11,llux",
		attr->size, attr->used, attr->major, attr->minor, attr->fsid, attr->fileid);
	Bprint(&bout, "\n");
}

void
lsdir(char *dir, Nfs3Handle *h)
{
	uchar *data, *p, *ep;
	Nfs3Attr attr;
	Nfs3Entry e;
	Nfs3Handle eh;
	u32int count;
	u1int eof;
	Nfs3Status ok;
	u64int cookie;
	
	cookie = 0;
	for(;;){
		ok = fsysreaddir(fsys, auth, h, 8192, cookie, &data, &count, &eof);
fprint(2, "got %d\n", count);
		if(ok != Nfs3Ok){
			nfs3errstr(ok);
			fprint(2, "ls %s: %r\n", dir);
			return;
		}
		p = data;
		ep = data+count;
		while(p<ep){
			if(nfs3entryunpack(p, ep, &p, &e) < 0){
				fprint(2, "%s: unpacking directory: %r\n", dir);
				break;
			}
			cookie = e.cookie;
			if((ok = fsyslookup(fsys, auth, h, e.name, &eh)) != Nfs3Ok){
				nfs3errstr(ok);
				fprint(2, "%s/%s: %r\n", dir, e.name);
				continue;
			}
			if((ok = fsysgetattr(fsys, auth, &eh, &attr)) != Nfs3Ok){
				nfs3errstr(ok);
				fprint(2, "%s/%s: %r\n", dir, e.name);
				continue;
			}
			ls(dir, e.name, &attr);
		}	
		free(data);
		if(eof)
			break;
	}
}

char*
cmdls(int argc, char **argv)
{
	int i;
	int dflag;
	char *e;
	Nfs3Handle h;
	Nfs3Attr attr;
	Nfs3Status ok;
	
	dflag = 0;
	ARGBEGIN{
	case 'd':
		dflag = 1;
		break;
	default:
		return "usage: ls [-d] [path...]";
	}ARGEND

	if(argc == 0){
		lsdir(nil, &cwd);
		Bflush(&bout);
		return nil;
	}
	
	for(i=0; i<argc; i++){
		if((e = walk(argv[i], &h)) != nil){
			fprint(2, "%s: %s\n", argv[i], e);
			continue;
		}
		if((ok = fsysgetattr(fsys, auth, &h, &attr)) != Nfs3Ok){
			nfs3errstr(ok);
			fprint(2, "%s: %r\n", argv[i]);
			continue;
		}
		if(attr.type != Nfs3FileDir || dflag)
			ls(argv[i], nil, &attr);
		else
			lsdir(argv[i], &h);
		Bflush(&bout);
	}
	return nil;
}

char*
cmdblock(int argc, char **argv)
{
	char *e;
	Nfs3Handle h;
	u64int bno;
	
	ARGBEGIN{
	default:
		return "usage: block path offset";
	}ARGEND
	
	if(argc != 2)
		return "usage: block path offset";

	if((e = walk(argv[0], &h)) != nil){
		fprint(2, "%s: %s\n", argv[0], e);
		return nil;
	}
	if((bno = fsys->fileblock(fsys, &h, strtoll(argv[1], 0, 0))) == 0){
		fprint(2, "%s: %r\n", argv[0]);
		return nil;
	}
	print("%#llux\n", bno);
	return nil;
}

char*
cmddisk(int argc, char **argv)
{
	Block *b;
	int delta, count, i;
	u64int offset;
	uchar *p;
	
	ARGBEGIN{
	default:
		return "usage: disk offset count";
	}ARGEND
	
	if(argc != 2)
		return "usage: disk offset count";

	offset = strtoull(argv[0], 0, 0);
	count = atoi(argv[1]);
	delta = offset%fsys->blocksize;
	
	b = diskread(disk, fsys->blocksize, offset-delta);
	if(b == nil){
		fprint(2, "diskread: %r\n");
		return nil;
	}
	p = b->data + delta;
	for(i=0; i<count; i++){
		Bprint(&bout, "%2.2ux ", p[i]);
		if(i%16 == 15)
			Bprint(&bout, "\n");
		else if(i%8 == 7)
			Bprint(&bout, " - ");
	}
	if(i%16 != 0)
		Bprint(&bout, "\n");
	Bflush(&bout);
	blockput(b);
	return nil;
}

void
usage(void)
{
	fprint(2, "usage: vftp score\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char **argv)
{
	char *err, *f[10], *p;
	int i, nf;
	uchar score[VtScoreSize];
	Nfs3Status ok;
	
	ARGBEGIN{
	case 'V':
		chattyventi++;
		break;
	default:
		usage();
	}ARGEND
	
	if(argc != 1)
		usage();

	fmtinstall('F', vtfcallfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('V', vtscorefmt);

	if(vtparsescore(argv[0], nil, score) < 0)
		sysfatal("bad score '%s'", argv[0]);
	if((z = vtdial(nil)) == nil)
		sysfatal("vtdial: %r");
	if(vtconnect(z) < 0)
		sysfatal("vtconnect: %r");
	if((c = vtcachealloc(z, 16384, 32)) == nil)
		sysfatal("vtcache: %r");
	if((disk = diskopenventi(c, score)) == nil)
		sysfatal("diskopenventi: %r");
	if((fsys = fsysopen(disk)) == nil)
		sysfatal("ffsopen: %r");

	fprint(2, "block size %d\n", fsys->blocksize);
	buf = emalloc(fsys->blocksize);
	if((ok = fsysroot(fsys, &root)) != Nfs3Ok){
		nfs3errstr(ok);
		sysfatal("accessing root: %r");
	}
	cwd = root;
	Binit(&bin, 0, OREAD);
	Binit(&bout, 1, OWRITE);
	
	while(fprint(2, "vftp> "), (p = Brdstr(&bin, '\n', 1)) != nil){
		if(p[0] == '#')
			continue;
		nf = tokenize(p, f, nelem(f));
		if(nf == 0)
			continue;
		for(i=0; i<nelem(cmdtab); i++){
			if(strcmp(f[0], cmdtab[i].s) == 0){
				if((err = cmdtab[i].fn(nf, f)) != nil)
					fprint(2, "%s\n", err);
				break;
			}
		}
		if(i == nelem(cmdtab))
			fprint(2, "unknown command '%s'\n", f[0]);
	}
	threadexitsall(nil);
}

