#include "stdinc.h"
#include "dat.h"
#include "fns.h"

static void	checkDirs(Fsck*);
static void	checkEpochs(Fsck*);
static void	checkLeak(Fsck*);
static void	closenop(Fsck*, Block*, u32int);
static void	clrenop(Fsck*, Block*, int);
static void	clrinop(Fsck*, char*, MetaBlock*, int, Block*);
static void	error(Fsck*, char*, ...);
static int	getBit(uchar*, u32int);
static int	printnop(char*, ...);
static void	setBit(uchar*, u32int);
static int	walkEpoch(Fsck *chk, Block *b, uchar score[VtScoreSize],
			int type, u32int tag, u32int epoch);
static void	warn(Fsck*, char*, ...);

#pragma varargck argpos error 2
#pragma varargck argpos printnop 1
#pragma varargck argpos warn 2

static Fsck*
checkInit(Fsck *chk)
{
	chk->cache = chk->fs->cache;
	chk->nblocks = cacheLocalSize(chk->cache, PartData);;
	chk->bsize = chk->fs->blockSize;
	chk->walkdepth = 0;
	chk->hint = 0;
	chk->quantum = chk->nblocks/100;
	if(chk->quantum == 0)
		chk->quantum = 1;
	if(chk->print == nil)
		chk->print = printnop;
	if(chk->clre == nil)
		chk->clre = clrenop;
	if(chk->close == nil)
		chk->close = closenop;
	if(chk->clri == nil)
		chk->clri = clrinop;
	return chk;
}

/*
 * BUG: Should merge checkEpochs and checkDirs so that
 * bad blocks are only reported once, and so that errors in checkEpochs
 * can have the affected file names attached, and so that the file system
 * is only read once.
 *
 * Also should summarize the errors instead of printing for every one
 * (e.g., XXX bad or unreachable blocks in /active/usr/rsc/foo).
 */

void
fsCheck(Fsck *chk)
{
	Block *b;
	Super super;

	checkInit(chk);
	b = superGet(chk->cache, &super);
	if(b == nil){
		chk->print("could not load super block: %r");
		return;
	}
	blockPut(b);

	chk->hint = super.active;
	checkEpochs(chk);

	chk->smap = vtmallocz(chk->nblocks/8+1);
	checkDirs(chk);
	vtfree(chk->smap);
}

static void checkEpoch(Fsck*, u32int);

/*
 * Walk through all the blocks in the write buffer.
 * Then we can look for ones we missed -- those are leaks.
 */
static void
checkEpochs(Fsck *chk)
{
	u32int e;
	uint nb;

	nb = chk->nblocks;
	chk->amap = vtmallocz(nb/8+1);
	chk->emap = vtmallocz(nb/8+1);
	chk->xmap = vtmallocz(nb/8+1);
	chk->errmap = vtmallocz(nb/8+1);

	for(e = chk->fs->ehi; e >= chk->fs->elo; e--){
		memset(chk->emap, 0, chk->nblocks/8+1);
		memset(chk->xmap, 0, chk->nblocks/8+1);
		checkEpoch(chk, e);
	}
	checkLeak(chk);
	vtfree(chk->amap);
	vtfree(chk->emap);
	vtfree(chk->xmap);
	vtfree(chk->errmap);
}

static void
checkEpoch(Fsck *chk, u32int epoch)
{
	u32int a;
	Block *b;
	Entry e;
	Label l;

	chk->print("checking epoch %ud...\n", epoch);

	for(a=0; a<chk->nblocks; a++){
		if(!readLabel(chk->cache, &l, (a+chk->hint)%chk->nblocks)){
			error(chk, "could not read label for addr 0x%.8#ux", a);
			continue;
		}
		if(l.tag == RootTag && l.epoch == epoch)
			break;
	}

	if(a == chk->nblocks){
		chk->print("could not find root block for epoch %ud", epoch);
		return;
	}

	a = (a+chk->hint)%chk->nblocks;
	b = cacheLocalData(chk->cache, a, BtDir, RootTag, OReadOnly, 0);
	if(b == nil){
		error(chk, "could not read root block 0x%.8#ux: %r", a);
		return;
	}

	/* no one should point at root blocks */
	setBit(chk->amap, a);
	setBit(chk->emap, a);
	setBit(chk->xmap, a);

	/*
	 * First entry is the rest of the file system.
	 * Second entry is link to previous epoch root,
	 * just a convenience to help the search.
	 */
	if(!entryUnpack(&e, b->data, 0)){
		error(chk, "could not unpack root block 0x%.8#ux: %r", a);
		blockPut(b);
		return;
	}
	walkEpoch(chk, b, e.score, BtDir, e.tag, epoch);
	if(entryUnpack(&e, b->data, 1))
		chk->hint = globalToLocal(e.score);
	blockPut(b);
}

/*
 * When b points at bb, need to check:
 *
 * (i) b.e in [bb.e, bb.eClose)
 * (ii) if b.e==bb.e,  then no other b' in e points at bb.
 * (iii) if !(b.state&Copied) and b.e==bb.e then no other b' points at bb.
 * (iv) if b is active then no other active b' points at bb.
 * (v) if b is a past life of b' then only one of b and b' is active
 *	(too hard to check)
 */
static int
walkEpoch(Fsck *chk, Block *b, uchar score[VtScoreSize], int type, u32int tag,
	u32int epoch)
{
	int i, ret;
	u32int addr, ep;
	Block *bb;
	Entry e;

	if(b && chk->walkdepth == 0 && chk->printblocks)
		chk->print("%V %d %#.8ux %#.8ux\n", b->score, b->l.type,
			b->l.tag, b->l.epoch);

	if(!chk->useventi && globalToLocal(score) == NilBlock)
		return 1;

	chk->walkdepth++;

	bb = cacheGlobal(chk->cache, score, type, tag, OReadOnly);
	if(bb == nil){
		error(chk, "could not load block %V type %d tag %ux: %r",
			score, type, tag);
		chk->walkdepth--;
		return 0;
	}
	if(chk->printblocks)
		chk->print("%*s%V %d %#.8ux %#.8ux\n", chk->walkdepth*2, "",
			score, type, tag, bb->l.epoch);

	ret = 0;
	addr = globalToLocal(score);
	if(addr == NilBlock){
		ret = 1;
		goto Exit;
	}

	if(b){
		/* (i) */
		if(b->l.epoch < bb->l.epoch || bb->l.epochClose <= b->l.epoch){
			error(chk, "walk: block %#ux [%ud, %ud) points at %#ux [%ud, %ud)",
				b->addr, b->l.epoch, b->l.epochClose,
				bb->addr, bb->l.epoch, bb->l.epochClose);
			goto Exit;
		}

		/* (ii) */
		if(b->l.epoch == epoch && bb->l.epoch == epoch){
			if(getBit(chk->emap, addr)){
				error(chk, "walk: epoch join detected: addr %#ux %L",
					bb->addr, &bb->l);
				goto Exit;
			}
			setBit(chk->emap, addr);
		}

		/* (iii) */
		if(!(b->l.state&BsCopied) && b->l.epoch == bb->l.epoch){
			if(getBit(chk->xmap, addr)){
				error(chk, "walk: copy join detected; addr %#ux %L",
					bb->addr, &bb->l);
				goto Exit;
			}
			setBit(chk->xmap, addr);
		}
	}

	/* (iv) */
	if(epoch == chk->fs->ehi){
		/*
		 * since epoch==fs->ehi is first, amap is same as
		 * ``have seen active''
		 */
		if(getBit(chk->amap, addr)){
			error(chk, "walk: active join detected: addr %#ux %L",
				bb->addr, &bb->l);
			goto Exit;
		}
		if(bb->l.state&BsClosed)
			error(chk, "walk: addr %#ux: block is in active tree but is closed",
				addr);
	}else
		if(!getBit(chk->amap, addr))
			if(!(bb->l.state&BsClosed)){
				// error(chk, "walk: addr %#ux: block is not in active tree, not closed (%d)",
				// addr, bb->l.epochClose);
				chk->close(chk, bb, epoch+1);
				chk->nclose++;
			}

	if(getBit(chk->amap, addr)){
		ret = 1;
		goto Exit;
	}
	setBit(chk->amap, addr);

	if(chk->nseen++%chk->quantum == 0)
		chk->print("check: visited %d/%d blocks (%.0f%%)\n",
			chk->nseen, chk->nblocks, chk->nseen*100./chk->nblocks);

	b = nil;		/* make sure no more refs to parent */
	USED(b);

	switch(type){
	default:
		/* pointer block */
		for(i = 0; i < chk->bsize/VtScoreSize; i++)
			if(!walkEpoch(chk, bb, bb->data + i*VtScoreSize,
			    type-1, tag, epoch)){
				setBit(chk->errmap, bb->addr);
				chk->clrp(chk, bb, i);
				chk->nclrp++;
			}
		break;
	case BtData:
		break;
	case BtDir:
		for(i = 0; i < chk->bsize/VtEntrySize; i++){
			if(!entryUnpack(&e, bb->data, i)){
				// error(chk, "walk: could not unpack entry: %ux[%d]: %r",
				//	addr, i);
				setBit(chk->errmap, bb->addr);
				chk->clre(chk, bb, i);
				chk->nclre++;
				continue;
			}
			if(!(e.flags & VtEntryActive))
				continue;
if(0)			fprint(2, "%x[%d] tag=%x snap=%d score=%V\n",
				addr, i, e.tag, e.snap, e.score);
			ep = epoch;
			if(e.snap != 0){
				if(e.snap >= epoch){
					// error(chk, "bad snap in entry: %ux[%d] snap = %ud: epoch = %ud",
					//	addr, i, e.snap, epoch);
					setBit(chk->errmap, bb->addr);
					chk->clre(chk, bb, i);
					chk->nclre++;
					continue;
				}
				continue;
			}
			if(e.flags & VtEntryLocal){
				if(e.tag < UserTag)
				if(e.tag != RootTag || tag != RootTag || i != 1){
					// error(chk, "bad tag in entry: %ux[%d] tag = %ux",
					//	addr, i, e.tag);
					setBit(chk->errmap, bb->addr);
					chk->clre(chk, bb, i);
					chk->nclre++;
					continue;
				}
			}else
				if(e.tag != 0){
					// error(chk, "bad tag in entry: %ux[%d] tag = %ux",
					//	addr, i, e.tag);
					setBit(chk->errmap, bb->addr);
					chk->clre(chk, bb, i);
					chk->nclre++;
					continue;
				}
			if(!walkEpoch(chk, bb, e.score, entryType(&e),
			    e.tag, ep)){
				setBit(chk->errmap, bb->addr);
				chk->clre(chk, bb, i);
				chk->nclre++;
			}
		}
		break;
	}

	ret = 1;

Exit:
	chk->walkdepth--;
	blockPut(bb);
	return ret;
}

/*
 * We've just walked the whole write buffer.  Notice blocks that
 * aren't marked available but that we didn't visit.  They are lost.
 */
static void
checkLeak(Fsck *chk)
{
	u32int a, nfree, nlost;
	Block *b;
	Label l;

	nfree = 0;
	nlost = 0;

	for(a = 0; a < chk->nblocks; a++){
		if(!readLabel(chk->cache, &l, a)){
			error(chk, "could not read label: addr 0x%ux %d %d: %r",
				a, l.type, l.state);
			continue;
		}
		if(getBit(chk->amap, a))
			continue;
		if(l.state == BsFree || l.epochClose <= chk->fs->elo ||
		    l.epochClose == l.epoch){
			nfree++;
			setBit(chk->amap, a);
			continue;
		}
		if(l.state&BsClosed)
			continue;
		nlost++;
//		warn(chk, "unreachable block: addr 0x%ux type %d tag 0x%ux "
//			"state %s epoch %ud close %ud", a, l.type, l.tag,
//			bsStr(l.state), l.epoch, l.epochClose);
		b = cacheLocal(chk->cache, PartData, a, OReadOnly);
		if(b == nil){
			error(chk, "could not read block 0x%#.8ux", a);
			continue;
		}
		chk->close(chk, b, 0);
		chk->nclose++;
		setBit(chk->amap, a);
		blockPut(b);
	}
	chk->print("fsys blocks: total=%ud used=%ud(%.1f%%) free=%ud(%.1f%%) lost=%ud(%.1f%%)\n",
		chk->nblocks,
		chk->nblocks - nfree-nlost,
		100.*(chk->nblocks - nfree - nlost)/chk->nblocks,
		nfree, 100.*nfree/chk->nblocks,
		nlost, 100.*nlost/chk->nblocks);
}


/*
 * Check that all sources in the tree are accessible.
 */
static Source *
openSource(Fsck *chk, Source *s, char *name, uchar *bm, u32int offset,
	u32int gen, int dir, MetaBlock *mb, int i, Block *b)
{
	Source *r;

	r = nil;
	if(getBit(bm, offset)){
		warn(chk, "multiple references to source: %s -> %d",
			name, offset);
		goto Err;
	}
	setBit(bm, offset);

	r = sourceOpen(s, offset, OReadOnly, 0);
	if(r == nil){
		warn(chk, "could not open source: %s -> %d: %r", name, offset);
		goto Err;
	}

	if(r->gen != gen){
		warn(chk, "source has been removed: %s -> %d", name, offset);
		goto Err;
	}

	if(r->dir != dir){
		warn(chk, "dir mismatch: %s -> %d", name, offset);
		goto Err;
	}
	return r;
Err:
	chk->clri(chk, name, mb, i, b);
	chk->nclri++;
	if(r)
		sourceClose(r);
	return nil;
}

typedef struct MetaChunk MetaChunk;
struct MetaChunk {
	ushort	offset;
	ushort	size;
	ushort	index;
};

static int
offsetCmp(const void *s0, const void *s1)
{
	MetaChunk *mc0, *mc1;

	mc0 = (MetaChunk*)s0;
	mc1 = (MetaChunk*)s1;
	if(mc0->offset < mc1->offset)
		return -1;
	if(mc0->offset > mc1->offset)
		return 1;
	return 0;
}

/*
 * Fsck that MetaBlock has reasonable header, sorted entries,
 */
static int
chkMetaBlock(MetaBlock *mb)
{
	MetaChunk *mc;
	int oo, o, n, i;
	uchar *p;

	mc = vtmalloc(mb->nindex*sizeof(MetaChunk));
	p = mb->buf + MetaHeaderSize;
	for(i = 0; i < mb->nindex; i++){
		mc[i].offset = p[0]<<8 | p[1];
		mc[i].size =   p[2]<<8 | p[3];
		mc[i].index = i;
		p += MetaIndexSize;
	}

	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);

	/* check block looks ok */
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	o = oo;
	n = 0;
	for(i = 0; i < mb->nindex; i++){
		o = mc[i].offset;
		n = mc[i].size;
		if(o < oo)
			goto Err;
		oo += n;
	}
	if(o+n > mb->size || mb->size - oo != mb->free)
		goto Err;

	vtfree(mc);
	return 1;

Err:
if(0){
	fprint(2, "metaChunks failed!\n");
	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;
	for(i=0; i<mb->nindex; i++){
		fprint(2, "\t%d: %d %d\n", i, mc[i].offset,
			mc[i].offset + mc[i].size);
		oo += mc[i].size;
	}
	fprint(2, "\tused=%d size=%d free=%d free2=%d\n",
		oo, mb->size, mb->free, mb->size - oo);
}
	vtfree(mc);
	return 0;
}

static void
scanSource(Fsck *chk, char *name, Source *r)
{
	u32int a, nb, o;
	Block *b;
	Entry e;

	if(!chk->useventi && globalToLocal(r->score)==NilBlock)
		return;
	if(!sourceGetEntry(r, &e)){
		error(chk, "could not get entry for %s", name);
		return;
	}
	a = globalToLocal(e.score);
	if(!chk->useventi && a==NilBlock)
		return;
	if(getBit(chk->smap, a))
		return;
	setBit(chk->smap, a);

	nb = (sourceGetSize(r) + r->dsize-1) / r->dsize;
	for(o = 0; o < nb; o++){
		b = sourceBlock(r, o, OReadOnly);
		if(b == nil){
			error(chk, "could not read block in data file %s", name);
			continue;
		}
		if(b->addr != NilBlock && getBit(chk->errmap, b->addr)){
			warn(chk, "previously reported error in block %ux is in file %s",
				b->addr, name);
		}
		blockPut(b);
	}
}

/*
 * Walk the source tree making sure that the BtData
 * sources containing directory entries are okay.
 */
static void
chkDir(Fsck *chk, char *name, Source *source, Source *meta)
{
	int i;
	u32int a1, a2, nb, o;
	char *s, *nn;
	uchar *bm;
	Block *b, *bb;
	DirEntry de;
	Entry e1, e2;
	MetaBlock mb;
	MetaEntry me;
	Source *r, *mr;

	if(!chk->useventi && globalToLocal(source->score)==NilBlock &&
	    globalToLocal(meta->score)==NilBlock)
		return;

	if(!sourceLock2(source, meta, OReadOnly)){
		warn(chk, "could not lock sources for %s: %r", name);
		return;
	}
	if(!sourceGetEntry(source, &e1) || !sourceGetEntry(meta, &e2)){
		warn(chk, "could not load entries for %s: %r", name);
		return;
	}
	a1 = globalToLocal(e1.score);
	a2 = globalToLocal(e2.score);
	if((!chk->useventi && a1==NilBlock && a2==NilBlock)
	|| (getBit(chk->smap, a1) && getBit(chk->smap, a2))){
		sourceUnlock(source);
		sourceUnlock(meta);
		return;
	}
	setBit(chk->smap, a1);
	setBit(chk->smap, a2);

	bm = vtmallocz(sourceGetDirSize(source)/8 + 1);

	nb = (sourceGetSize(meta) + meta->dsize - 1)/meta->dsize;
	for(o = 0; o < nb; o++){
		b = sourceBlock(meta, o, OReadOnly);
		if(b == nil){
			error(chk, "could not read block in meta file: %s[%ud]: %r",
				name, o);
			continue;
		}
if(0)		fprint(2, "source %V:%d block %d addr %d\n", source->score,
			source->offset, o, b->addr);
		if(b->addr != NilBlock && getBit(chk->errmap, b->addr))
			warn(chk, "previously reported error in block %ux is in %s",
				b->addr, name);

		if(!mbUnpack(&mb, b->data, meta->dsize)){
			error(chk, "could not unpack meta block: %s[%ud]: %r",
				name, o);
			blockPut(b);
			continue;
		}
		if(!chkMetaBlock(&mb)){
			error(chk, "bad meta block: %s[%ud]: %r", name, o);
			blockPut(b);
			continue;
		}
		s = nil;
		for(i=mb.nindex-1; i>=0; i--){
			meUnpack(&me, &mb, i);
			if(!deUnpack(&de, &me)){
				error(chk,
				  "could not unpack dir entry: %s[%ud][%d]: %r",
					name, o, i);
				continue;
			}
			if(s && strcmp(s, de.elem) <= 0)
				error(chk,
			   "dir entry out of order: %s[%ud][%d] = %s last = %s",
					name, o, i, de.elem, s);
			vtfree(s);
			s = vtstrdup(de.elem);
			nn = smprint("%s/%s", name, de.elem);
			if(nn == nil){
				error(chk, "out of memory");
				continue;
			}
			if(chk->printdirs)
				if(de.mode&ModeDir)
					chk->print("%s/\n", nn);
			if(chk->printfiles)
				if(!(de.mode&ModeDir))
					chk->print("%s\n", nn);
			if(!(de.mode & ModeDir)){
				r = openSource(chk, source, nn, bm, de.entry,
					de.gen, 0, &mb, i, b);
				if(r != nil){
					if(sourceLock(r, OReadOnly)){
						scanSource(chk, nn, r);
						sourceUnlock(r);
					}
					sourceClose(r);
				}
				deCleanup(&de);
				free(nn);
				continue;
			}

			r = openSource(chk, source, nn, bm, de.entry,
				de.gen, 1, &mb, i, b);
			if(r == nil){
				deCleanup(&de);
				free(nn);
				continue;
			}

			mr = openSource(chk, source, nn, bm, de.mentry,
				de.mgen, 0, &mb, i, b);
			if(mr == nil){
				sourceClose(r);
				deCleanup(&de);
				free(nn);
				continue;
			}

			if(!(de.mode&ModeSnapshot) || chk->walksnapshots)
				chkDir(chk, nn, r, mr);

			sourceClose(mr);
			sourceClose(r);
			deCleanup(&de);
			free(nn);
			deCleanup(&de);

		}
		vtfree(s);
		blockPut(b);
	}

	nb = sourceGetDirSize(source);
	for(o=0; o<nb; o++){
		if(getBit(bm, o))
			continue;
		r = sourceOpen(source, o, OReadOnly, 0);
		if(r == nil)
			continue;
		warn(chk, "non referenced entry in source %s[%d]", name, o);
		if((bb = sourceBlock(source, o/(source->dsize/VtEntrySize),
		    OReadOnly)) != nil){
			if(bb->addr != NilBlock){
				setBit(chk->errmap, bb->addr);
				chk->clre(chk, bb, o%(source->dsize/VtEntrySize));
				chk->nclre++;
			}
			blockPut(bb);
		}
		sourceClose(r);
	}

	sourceUnlock(source);
	sourceUnlock(meta);
	vtfree(bm);
}

static void
checkDirs(Fsck *chk)
{
	Source *r, *mr;

	sourceLock(chk->fs->source, OReadOnly);
	r = sourceOpen(chk->fs->source, 0, OReadOnly, 0);
	mr = sourceOpen(chk->fs->source, 1, OReadOnly, 0);
	sourceUnlock(chk->fs->source);
	chkDir(chk, "", r, mr);

	sourceClose(r);
	sourceClose(mr);
}

static void
setBit(uchar *bmap, u32int addr)
{
	if(addr == NilBlock)
		return;

	bmap[addr>>3] |= 1 << (addr & 7);
}

static int
getBit(uchar *bmap, u32int addr)
{
	if(addr == NilBlock)
		return 0;

	return (bmap[addr>>3] >> (addr & 7)) & 1;
}

static void
error(Fsck *chk, char *fmt, ...)
{
	char buf[256];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof buf, fmt, arg);
	va_end(arg);

	chk->print("error: %s\n", buf);

//	if(nerr++ > 20)
//		sysfatal("too many errors");
}

static void
warn(Fsck *chk, char *fmt, ...)
{
	char buf[256];
	va_list arg;

	va_start(arg, fmt);
	vseprint(buf, buf+sizeof buf, fmt, arg);
	va_end(arg);

	chk->print("error: %s\n", buf);
}

static void
clrenop(Fsck *chk, Block *b, int i)
{
	USED(chk);
	USED(b);
	USED(i);
}

static void
closenop(Fsck *chk, Block *b, u32int i)
{
	USED(chk);
	USED(b);
	USED(i);
}

static void
clrinop(Fsck *chk, char *c, MetaBlock *mb, int i, Block *b)
{
	USED(chk);
	USED(c);
	USED(mb);
	USED(i);
	USED(b);
}

static int
printnop(char *c, ...)
{
	USED(c);
	return 0;
}
