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

/*
 * Write a lump to disk.  Updates ia with an index address
 * for the newly-written lump.  Upon return, the lump will
 * have been placed in the disk cache but will likely not be on disk yet.
 */
int
storeclump(Index *ix, ZBlock *zb, u8int *sc, int type, u32int creator, IAddr *ia)
{
	ZBlock *cb;
	Clump cl;
	u64int a;
	u8int bh[VtScoreSize];
	int size, dsize;

	trace(TraceLump, "storeclump enter", sc, type);
	size = zb->len;
	if(size > VtMaxLumpSize){
		seterr(EStrange, "lump too large");
		return -1;
	}
	if(vttypevalid(type) < 0){
		seterr(EStrange, "invalid lump type");
		return -1;
	}

	if(0){
		scoremem(bh, zb->data, size);
		if(scorecmp(sc, bh) != 0){
			seterr(ECorrupt, "storing clump: corrupted; expected=%V got=%V, size=%d", sc, bh, size);
			return -1;
		}
	}

	cb = alloczblock(size + ClumpSize + U32Size, 0, 0);
	if(cb == nil)
		return -1;

	cl.info.type = type;
	cl.info.uncsize = size;
	cl.creator = creator;
	cl.time = now();
	scorecp(cl.info.score, sc);

	trace(TraceLump, "storeclump whackblock");
	dsize = whackblock(&cb->data[ClumpSize], zb->data, size);
	if(dsize > 0 && dsize < size){
		cl.encoding = ClumpECompress;
	}else{
		if(dsize > size){
			fprint(2, "whack error: dsize=%d size=%d\n", dsize, size);
			abort();
		}
		cl.encoding = ClumpENone;
		dsize = size;
		memmove(&cb->data[ClumpSize], zb->data, size);
	}
	memset(cb->data+ClumpSize+dsize, 0, 4);
	cl.info.size = dsize;

	ia->addr = 0;
	ia->type = type;
	ia->size = size;
	ia->blocks = (dsize + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog;

	a = writeiclump(ix, &cl, cb->data, &ia->addr);

	trace(TraceLump, "storeclump exit %lld", a);

	freezblock(cb);
	if(a == TWID64)
		return -1;

/*
	qlock(&stats.lock);
	stats.clumpwrites++;
	stats.clumpbwrites += size;
	stats.clumpbcomp += dsize;
	qunlock(&stats.lock);
*/

	return 0;
}

u32int
clumpmagic(Arena *arena, u64int aa)
{
	u8int buf[U32Size];

	if(readarena(arena, aa, buf, U32Size) < 0)
		return TWID32;
	return unpackmagic(buf);
}

/*
 * fetch a block based at addr.
 * score is filled in with the block's score.
 * blocks is roughly the length of the clump on disk;
 * if zero, the length is unknown.
 */
ZBlock*
loadclump(Arena *arena, u64int aa, int blocks, Clump *cl, u8int *score, int verify)
{
	Unwhack uw;
	ZBlock *zb, *cb;
	u8int bh[VtScoreSize], *buf;
	u32int n;
	int nunc;

/*
	qlock(&stats.lock);
	stats.clumpreads++;
	qunlock(&stats.lock);
*/

	if(blocks <= 0)
		blocks = 1;

	trace(TraceLump, "loadclump enter");

	cb = alloczblock(blocks << ABlockLog, 0, 0);
	if(cb == nil)
		return nil;
	n = readarena(arena, aa, cb->data, blocks << ABlockLog);
	if(n < ClumpSize){
		if(n != 0)
			seterr(ECorrupt, "loadclump read less than a header");
		freezblock(cb);
		return nil;
	}
	trace(TraceLump, "loadclump unpack");
	if(unpackclump(cl, cb->data, arena->clumpmagic) < 0){
		seterr(ECorrupt, "loadclump %s %llud: %r", arena->name, aa);
		freezblock(cb);
		return nil;
	}
	n -= ClumpSize;
	if(n < cl->info.size){
		freezblock(cb);
		n = cl->info.size;
		cb = alloczblock(n, 0, 0);
		if(cb == nil)
			return nil;
		if(readarena(arena, aa + ClumpSize, cb->data, n) != n){
			seterr(ECorrupt, "loadclump read too little data");
			freezblock(cb);
			return nil;
		}
		buf = cb->data;
	}else
		buf = cb->data + ClumpSize;

	scorecp(score, cl->info.score);

	zb = alloczblock(cl->info.uncsize, 0, 0);
	if(zb == nil){
		freezblock(cb);
		return nil;
	}
	switch(cl->encoding){
	case ClumpECompress:
		trace(TraceLump, "loadclump decompress");
		unwhackinit(&uw);
		nunc = unwhack(&uw, zb->data, cl->info.uncsize, buf, cl->info.size);
		if(nunc != cl->info.uncsize){
			if(nunc < 0)
				seterr(ECorrupt, "decompression of %llud failed: %s", aa, uw.err);
			else
				seterr(ECorrupt, "decompression of %llud gave partial block: %d/%d\n", aa, nunc, cl->info.uncsize);
			freezblock(cb);
			freezblock(zb);
			return nil;
		}
		break;
	case ClumpENone:
		if(cl->info.size != cl->info.uncsize){
			seterr(ECorrupt, "loading clump: bad uncompressed size for uncompressed block %llud", aa);
			freezblock(cb);
			freezblock(zb);
			return nil;
		}
		scoremem(bh, buf, cl->info.uncsize);
		if(scorecmp(cl->info.score, bh) != 0)
			seterr(ECorrupt, "pre-copy sha1 wrong at %s %llud: expected=%V got=%V", arena->name, aa, cl->info.score, bh);
		memmove(zb->data, buf, cl->info.uncsize);
		break;
	default:
		seterr(ECorrupt, "unknown encoding in loadlump %llud", aa);
		freezblock(cb);
		freezblock(zb);
		return nil;
	}
	freezblock(cb);

	if(verify){
		trace(TraceLump, "loadclump verify");
		scoremem(bh, zb->data, cl->info.uncsize);
		if(scorecmp(cl->info.score, bh) != 0){
			seterr(ECorrupt, "loading clump: corrupted at %s %llud; expected=%V got=%V", arena->name, aa, cl->info.score, bh);
			freezblock(zb);
			return nil;
		}
		if(vttypevalid(cl->info.type) < 0){
			seterr(ECorrupt, "loading lump at %s %llud: invalid lump type %d", arena->name, aa, cl->info.type);
			freezblock(zb);
			return nil;
		}
	}

	trace(TraceLump, "loadclump exit");
/*
	qlock(&stats.lock);
	stats.clumpbreads += cl->info.size;
	stats.clumpbuncomp += cl->info.uncsize;
	qunlock(&stats.lock);
*/
	return zb;
}
