#include <u.h>
#include <libc.h>
#include <venti.h>
#include <libsec.h>
#include <thread.h>
#include <avl.h>
#include <bin.h>

enum
{
	// XXX What to do here?
	VtMaxLumpSize = 65535,
};

int changes;
int rewrite;
int ignoreerrors;
int fast;
int verbose;
int nskip;
int nwrite;

VtConn *zsrc, *zdst;
uchar zeroscore[VtScoreSize];	/* all zeros */

typedef struct ScoreTree ScoreTree;
struct ScoreTree
{
	Avl avl;
	uchar score[VtScoreSize];
	int type;
};

Avltree *scoretree;
Bin *scorebin;

static int
scoretreecmp(Avl *va, Avl *vb)
{
	ScoreTree *a, *b;
	int i;

	a = (ScoreTree*)va;
	b = (ScoreTree*)vb;

	i = memcmp(a->score, b->score, VtScoreSize);
	if(i != 0)
		return i;
	return a->type - b->type;
}

static int
havevisited(uchar score[VtScoreSize], int type)
{
	ScoreTree a;
	
	if(scoretree == nil)
		return 0;
	memmove(a.score, score, VtScoreSize);
	a.type = type;
	return lookupavl(scoretree, &a.avl) != nil;
}

static void
markvisited(uchar score[VtScoreSize], int type)
{
	ScoreTree *a;
	Avl *old;

	if(scoretree == nil)
		return;
	a = binalloc(&scorebin, sizeof *a, 1);
	memmove(a->score, score, VtScoreSize);
	a->type = type;
	insertavl(scoretree, &a->avl, &old);
}

void
usage(void)
{
	fprint(2, "usage: copy [-fimrVv] [-t type] srchost dsthost score\n");
	threadexitsall("usage");
}

void
walk(uchar score[VtScoreSize], uint type, int base, int depth)
{
	int i, n;
	uchar *buf;
	uchar nscore[VtScoreSize];
	VtEntry e;
	VtRoot root;

	if(verbose){
		for(i = 0; i < depth; i++)
			fprint(2, " ");
		fprint(2, "-> %d %d %d %V\n", depth, type, base, score);
	}

	if(memcmp(score, vtzeroscore, VtScoreSize) == 0 || memcmp(score, zeroscore, VtScoreSize) == 0)
		return;
	
	if(havevisited(score, type)){
		nskip++;
		return;
	}

	buf = vtmallocz(VtMaxLumpSize);
	if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){
		if(verbose)
			fprint(2, "skip %V\n", score);
		free(buf);
		return;
	}

	n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
	if(n < 0){
		if(rewrite){
			changes++;
			memmove(score, vtzeroscore, VtScoreSize);
		}else if(!ignoreerrors)
			sysfatal("reading block %V (type %d): %r", score, type);
		return;
	}

	switch(type){
	case VtRootType:
		if(vtrootunpack(&root, buf) < 0){
			fprint(2, "warning: could not unpack root in %V %d\n", score, type);
			break;
		}
		walk(root.prev, VtRootType, 0, depth+1);
		walk(root.score, VtDirType, 0, depth+1);
		if(rewrite)
			vtrootpack(&root, buf);	/* walk might have changed score */
		break;

	case VtDirType:
		for(i=0; i<n/VtEntrySize; i++){
			if(vtentryunpack(&e, buf, i) < 0){
				fprint(2, "warning: could not unpack entry #%d in %V %d\n", i, score, type);
				continue;
			}
			if(!(e.flags & VtEntryActive))
				continue;
			walk(e.score, e.type, e.type&VtTypeBaseMask, depth+1);
			/*
			 * Don't repack unless we're rewriting -- some old 
			 * vac files have psize==0 and dsize==0, and these
			 * get rewritten by vtentryunpack to have less strange
			 * block sizes.  So vtentryunpack; vtentrypack does not
			 * guarantee to preserve the exact bytes in buf.
			 */
			if(rewrite)
				vtentrypack(&e, buf, i);
		}
		break;

	case VtDataType:
		break;

	default:	/* pointers */
		for(i=0; i<n; i+=VtScoreSize)
			if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0)
				walk(buf+i, type-1, base, depth+1);
		break;
	}

	nwrite++;
	if(vtwrite(zdst, nscore, type, buf, n) < 0){
		/* figure out score for better error message */
		/* can't use input argument - might have changed contents */
		n = vtzerotruncate(type, buf, n);
		sha1(buf, n, score, nil);
		sysfatal("writing block %V (type %d): %r", score, type);
	}
	if(!rewrite && memcmp(score, nscore, VtScoreSize) != 0)
		sysfatal("not rewriting: wrote %V got %V", score, nscore);	

	if((type !=0 || base !=0) && verbose){
		n = vtzerotruncate(type, buf, n);
		sha1(buf, n, score, nil);

		for(i = 0; i < depth; i++)
			fprint(2, " ");
		fprint(2, "<- %V\n", score);
	}
	
	markvisited(score, type);
	free(buf);
}

void
threadmain(int argc, char *argv[])
{
	int type, n;
	uchar score[VtScoreSize];
	uchar *buf;
	char *prefix;

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

	type = -1;
	ARGBEGIN{
	case 'V':
		chattyventi++;
		break;
	case 'f':
		fast = 1;
		break;
	case 'i':
		if(rewrite)
			usage();
		ignoreerrors = 1;
		break;
	case 'm':
		scoretree = mkavltree(scoretreecmp);
		break;
	case 'r':
		if(ignoreerrors)
			usage();
		rewrite = 1;
		break;
	case 't':
		type = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	default:
		usage();
		break;
	}ARGEND

	if(argc != 3)
		usage();

	if(vtparsescore(argv[2], &prefix, score) < 0)
		sysfatal("could not parse score: %r");

	buf = vtmallocz(VtMaxLumpSize);

	zsrc = vtdial(argv[0]);
	if(zsrc == nil)
		sysfatal("could not dial src server: %r");
	if(vtconnect(zsrc) < 0)
		sysfatal("vtconnect src: %r");

	zdst = vtdial(argv[1]);
	if(zdst == nil)
		sysfatal("could not dial dst server: %r");
	if(vtconnect(zdst) < 0)
		sysfatal("vtconnect dst: %r");

	if(type != -1){
		n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
		if(n < 0)
			sysfatal("could not read block: %r");
	}else{
		for(type=0; type<VtMaxType; type++){
			n = vtread(zsrc, score, type, buf, VtMaxLumpSize);
			if(n >= 0)
				break;
		}
		if(type == VtMaxType)
			sysfatal("could not find block %V of any type", score);
	}

	walk(score, type, VtDirType, 0);
	if(changes)
		print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);

	if(verbose)
		print("%d skipped, %d written\n", nskip, nwrite);

	if(vtsync(zdst) < 0)
		sysfatal("could not sync dst server: %r");

	threadexitsall(0);
}
