#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;
	AState as;

	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();
	}

	if(used != arena->memstats.used
	|| clumps != arena->memstats.clumps
	|| cclumps != arena->memstats.cclumps
	|| uncsize != arena->memstats.uncsize)
		err |= SyncHeader;
	if(start && (err&SyncHeader)){
		trace(TraceProc, "syncarena setdcachestate");
		as.arena = arena;
		as.aa = start+arena->memstats.used;
		as.stats = arena->memstats;
		setdcachestate(&as);
	}

	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;
}
