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

static int	writeclumphead(Arena *arena, u64int aa, Clump *cl);
static int	writeclumpmagic(Arena *arena, u64int aa, u32int magic);

int
clumpinfocmp(ClumpInfo *c, ClumpInfo *d)
{
	return c->type != d->type
		|| c->size != d->size
		|| c->uncsize != d->uncsize
		|| scorecmp(c->score, d->score)!=0;
}

/*
 * synchronize the clump info directory with
 * with the clumps actually stored in the arena.
 * the directory should be at least as up to date
 * as the arena's trailer.
 *
 * checks/updates at most n clumps.
 *
 * returns 0 if ok, flags if error occurred
 */
int
syncarena(Arena *arena, u64int start, u32int n, int zok, int fix)
{
	ZBlock *lump;
	Clump cl;
	ClumpInfo ci;
	static ClumpInfo zci = { .type = -1 };
	u8int score[VtScoreSize];
	u64int uncsize, used, aa;
	u32int clump, clumps, cclumps, magic;
	int err, flush, broken;

	used = arena->memstats.used;
	clumps = arena->memstats.clumps;
	cclumps = arena->memstats.cclumps;
	uncsize = arena->memstats.uncsize;
	trace(TraceProc, "syncarena start");
	flush = 0;
	err = 0;
	for(; n; n--){
		aa = arena->memstats.used;
		clump = arena->memstats.clumps;
		magic = clumpmagic(arena, aa);
		if(magic == ClumpFreeMagic)
			break;
		if(magic != arena->clumpmagic){
			fprint(2, "%s: illegal clump magic number=%#8.8ux at clump=%d\n", arena->name, magic, clump);
			/* err |= SyncDataErr; */
			if(fix && writeclumpmagic(arena, aa, ClumpFreeMagic) < 0){
				fprint(2, "can't write corrected clump free magic: %r");
				err |= SyncFixErr;
			}
			break;
		}

		broken = 0;
		lump = loadclump(arena, aa, 0, &cl, score, 0);
		if(lump == nil){
			fprint(2, "%s: clump=%d failed to read correctly: %r\n", arena->name, clump);
			break;
			err |= SyncDataErr;
		}else if(cl.info.type != VtCorruptType){
			scoremem(score, lump->data, cl.info.uncsize);
			if(scorecmp(cl.info.score, score) != 0){
				/* ignore partially written block */
				if(cl.encoding == ClumpENone)
					break;
				fprint(2, "%s: clump=%d has mismatched score\n", arena->name, clump);
				err |= SyncDataErr;
				broken = 1;
			}else if(vttypevalid(cl.info.type) < 0){
				fprint(2, "%s: clump=%d has invalid type %d", arena->name, clump, cl.info.type);
				err |= SyncDataErr;
				broken = 1;
			}
			if(broken && fix){
				cl.info.type = VtCorruptType;
				if(writeclumphead(arena, aa, &cl) < 0){
					fprint(2, "%s: can't write corrected clump header: %r", arena->name);
					err |= SyncFixErr;
				}
			}
		}
		freezblock(lump);
		arena->memstats.used += ClumpSize + cl.info.size;

		arena->memstats.clumps++;
		if(!broken && readclumpinfo(arena, clump, &ci)<0){
			fprint(2, "%s: arena directory read failed\n", arena->name);
			broken = 1;
		}else if(!broken && clumpinfocmp(&ci, &cl.info)!=0){
			if(clumpinfocmp(&ci, &zci) == 0){
				err |= SyncCIZero;
				if(!zok)
					fprint(2, "%s: unwritten clump info for clump=%d\n", arena->name, clump);
			}else{
				err |= SyncCIErr;
				fprint(2, "%s: bad clump info for clump=%d\n", arena->name, clump);
				fprint(2, "\texpected score=%V type=%d size=%d uncsize=%d\n",
					cl.info.score, cl.info.type, cl.info.size, cl.info.uncsize);
				fprint(2, "\tfound score=%V type=%d size=%d uncsize=%d\n",
					ci.score, ci.type, ci.size, ci.uncsize);
			}
			broken = 1;
		}
		if(broken && fix){
			flush = 1;
			ci = cl.info;
			if(writeclumpinfo(arena, clump, &ci) < 0){
				fprint(2, "%s: can't write correct clump directory: %r\n", arena->name);
				err |= SyncFixErr;
			}
		}
		trace(TraceProc, "syncarena unindexed clump %V %d", cl.info.score, arena->memstats.clumps);

		arena->memstats.uncsize += cl.info.uncsize;
		if(cl.info.size < cl.info.uncsize)
			arena->memstats.cclumps++;
	}

	if(flush){
		trace(TraceProc, "syncarena flush");
		arena->wtime = now();
		if(arena->ctime == 0 && arena->memstats.clumps)
			arena->ctime = arena->wtime;
		flushdcache();
	}

fprint(2, "arena %s: start=%lld fix=%d flush=%d %lld->%lld %ud->%ud %ud->%ud %lld->%lld\n",
	arena->name,
	start,
	fix,
	flush,
	used, arena->memstats.used,
	clumps, arena->memstats.clumps,
	cclumps, arena->memstats.cclumps,
	uncsize, arena->memstats.uncsize);

	if(used != arena->memstats.used
	|| clumps != arena->memstats.clumps
	|| cclumps != arena->memstats.cclumps
	|| uncsize != arena->memstats.uncsize)
		err |= SyncHeader;
	return err;
}

static int
writeclumphead(Arena *arena, u64int aa, Clump *cl)
{
	ZBlock *zb;
	int bad;

	zb = alloczblock(ClumpSize, 0, arena->blocksize);
	if(zb == nil)
		return -1;
	bad = packclump(cl, zb->data, arena->clumpmagic)<0
		|| writearena(arena, aa, zb->data, ClumpSize) != ClumpSize;
	freezblock(zb);
	return bad ? -1 : 0;
}

static int
writeclumpmagic(Arena *arena, u64int aa, u32int magic)
{
	u8int buf[U32Size];

	packmagic(magic, buf);
	return writearena(arena, aa, buf, U32Size) == U32Size;
}
