#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, 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->used;
	clumps = arena->clumps;
	cclumps = arena->cclumps;
	uncsize = arena->uncsize;

	flush = 0;
	err = 0;
	for(; n; n--){
		aa = arena->used;
		clump = arena->clumps;
		magic = clumpmagic(arena, aa);
		if(magic == ClumpFreeMagic)
			break;
		if(magic != ClumpMagic){
			fprint(2, "illegal clump magic number=%#8.8ux at clump=%d\n", magic, clump);
			err |= SyncDataErr;
//ZZZ write a zero here?
			if(0 && fix && writeclumpmagic(arena, aa, ClumpFreeMagic) < 0){
				fprint(2, "can't write corrected clump free magic: %r");
				err |= SyncFixErr;
			}
			break;
		}
		arena->clumps++;

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

		if(!broken && readclumpinfo(arena, clump, &ci)<0){
			fprint(2, "arena directory read failed\n");
			broken = 1;
		}else if(!broken && clumpinfocmp(&ci, &cl.info)!=0){
			if(clumpinfocmp(&ci, &zci) == 0){
				err |= SyncCIZero;
				if(!zok)
					fprint(2, "unwritten clump info for clump=%d\n", clump);
			}else{
				err |= SyncCIErr;
				fprint(2, "bad clump info for clump=%d\n", 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, "can't write correct clump directory: %r\n");
				err |= SyncFixErr;
			}
		}

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

	if(flush){
		arena->wtime = now();
		if(arena->ctime == 0 && arena->clumps)
			arena->ctime = arena->wtime;
		if(flushciblocks(arena) < 0){
			fprint(2, "can't flush arena directory cache: %r");
			err |= SyncFixErr;
		}
		flushdcache();
	}

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

	return err;
}

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

	zb = alloczblock(ClumpSize, 0);
	if(zb == nil)
		return -1;
	bad = packclump(cl, zb->data)<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;
}
