#include "sam.h"

enum
{
	Slop = 100,	/* room to grow with reallocation */
};

static
void
sizecache(Buffer *b, uint n)
{
	if(n <= b->cmax)
		return;
	b->cmax = n+Slop;
	b->c = runerealloc(b->c, b->cmax);
}

static
void
addblock(Buffer *b, uint i, uint n)
{
	if(i > b->nbl)
		panic("internal error: addblock");

	b->bl = realloc(b->bl, (b->nbl+1)*sizeof b->bl[0]);
	if(i < b->nbl)
		memmove(b->bl+i+1, b->bl+i, (b->nbl-i)*sizeof(Block*));
	b->bl[i] = disknewblock(disk, n);
	b->nbl++;
}


static
void
delblock(Buffer *b, uint i)
{
	if(i >= b->nbl)
		panic("internal error: delblock");

	diskrelease(disk, b->bl[i]);
	b->nbl--;
	if(i < b->nbl)
		memmove(b->bl+i, b->bl+i+1, (b->nbl-i)*sizeof(Block*));
	b->bl = realloc(b->bl, b->nbl*sizeof b->bl[0]);
}

/*
 * Move cache so b->cq <= q0 < b->cq+b->cnc.
 * If at very end, q0 will fall on end of cache block.
 */

static
void
flush(Buffer *b)
{
	if(b->cdirty || b->cnc==0){
		if(b->cnc == 0)
			delblock(b, b->cbi);
		else
			diskwrite(disk, &b->bl[b->cbi], b->c, b->cnc);
		b->cdirty = FALSE;
	}
}

static
void
setcache(Buffer *b, uint q0)
{
	Block **blp, *bl;
	uint i, q;

	if(q0 > b->nc)
		panic("internal error: setcache");
	/*
	 * flush and reload if q0 is not in cache.
	 */
	if(b->nc == 0 || (b->cq<=q0 && q0<b->cq+b->cnc))
		return;
	/*
	 * if q0 is at end of file and end of cache, continue to grow this block
	 */
	if(q0==b->nc && q0==b->cq+b->cnc && b->cnc<=Maxblock)
		return;
	flush(b);
	/* find block */
	if(q0 < b->cq){
		q = 0;
		i = 0;
	}else{
		q = b->cq;
		i = b->cbi;
	}
	blp = &b->bl[i];
	while(q+(*blp)->u.n <= q0 && q+(*blp)->u.n < b->nc){
		q += (*blp)->u.n;
		i++;
		blp++;
		if(i >= b->nbl)
			panic("block not found");
	}
	bl = *blp;
	/* remember position */
	b->cbi = i;
	b->cq = q;
	sizecache(b, bl->u.n);
	b->cnc = bl->u.n;
	/*read block*/
	diskread(disk, bl, b->c, b->cnc);
}

void
bufinsert(Buffer *b, uint q0, Rune *s, uint n)
{
	uint i, m, t, off;

	if(q0 > b->nc)
		panic("internal error: bufinsert");

	while(n > 0){
		setcache(b, q0);
		off = q0-b->cq;
		if(b->cnc+n <= Maxblock){
			/* Everything fits in one block. */
			t = b->cnc+n;
			m = n;
			if(b->bl == nil){	/* allocate */
				if(b->cnc != 0)
					panic("internal error: bufinsert1 cnc!=0");
				addblock(b, 0, t);
				b->cbi = 0;
			}
			sizecache(b, t);
			runemove(b->c+off+m, b->c+off, b->cnc-off);
			runemove(b->c+off, s, m);
			b->cnc = t;
			goto Tail;
		}
		/*
		 * We must make a new block.  If q0 is at
		 * the very beginning or end of this block,
		 * just make a new block and fill it.
		 */
		if(q0==b->cq || q0==b->cq+b->cnc){
			if(b->cdirty)
				flush(b);
			m = min(n, Maxblock);
			if(b->bl == nil){	/* allocate */
				if(b->cnc != 0)
					panic("internal error: bufinsert2 cnc!=0");
				i = 0;
			}else{
				i = b->cbi;
				if(q0 > b->cq)
					i++;
			}
			addblock(b, i, m);
			sizecache(b, m);
			runemove(b->c, s, m);
			b->cq = q0;
			b->cbi = i;
			b->cnc = m;
			goto Tail;
		}
		/*
		 * Split the block; cut off the right side and
		 * let go of it.
		 */
		m = b->cnc-off;
		if(m > 0){
			i = b->cbi+1;
			addblock(b, i, m);
			diskwrite(disk, &b->bl[i], b->c+off, m);
			b->cnc -= m;
		}
		/*
		 * Now at end of block.  Take as much input
		 * as possible and tack it on end of block.
		 */
		m = min(n, Maxblock-b->cnc);
		sizecache(b, b->cnc+m);
		runemove(b->c+b->cnc, s, m);
		b->cnc += m;
  Tail:
		b->nc += m;
		q0 += m;
		s += m;
		n -= m;
		b->cdirty = TRUE;
	}
}

void
bufdelete(Buffer *b, uint q0, uint q1)
{
	uint m, n, off;

	if(!(q0<=q1 && q0<=b->nc && q1<=b->nc))
		panic("internal error: bufdelete");
	while(q1 > q0){
		setcache(b, q0);
		off = q0-b->cq;
		if(q1 > b->cq+b->cnc)
			n = b->cnc - off;
		else
			n = q1-q0;
		m = b->cnc - (off+n);
		if(m > 0)
			runemove(b->c+off, b->c+off+n, m);
		b->cnc -= n;
		b->cdirty = TRUE;
		q1 -= n;
		b->nc -= n;
	}
}

uint
bufload(Buffer *b, uint q0, int fd, int *nulls)
{
	char *p;
	Rune *r;
	int l, m, n, nb, nr;
	uint q1;

	if(q0 > b->nc)
		panic("internal error: bufload");
	p = malloc((Maxblock+UTFmax+1)*sizeof p[0]);
	if(p == nil)
		panic("bufload: malloc failed");
	r = runemalloc(Maxblock);
	m = 0;
	n = 1;
	q1 = q0;
	/*
	 * At top of loop, may have m bytes left over from
	 * last pass, possibly representing a partial rune.
	 */
	while(n > 0){
		n = read(fd, p+m, Maxblock);
		if(n < 0){
			error(Ebufload);
			break;
		}
		m += n;
		p[m] = 0;
		l = m;
		if(n > 0)
			l -= UTFmax;
		cvttorunes(p, l, r, &nb, &nr, nulls);
		memmove(p, p+nb, m-nb);
		m -= nb;
		bufinsert(b, q1, r, nr);
		q1 += nr;
	}
	free(p);
	free(r);
	return q1-q0;
}

void
bufread(Buffer *b, uint q0, Rune *s, uint n)
{
	uint m;

	if(!(q0<=b->nc && q0+n<=b->nc))
		panic("bufread: internal error");

	while(n > 0){
		setcache(b, q0);
		m = min(n, b->cnc-(q0-b->cq));
		runemove(s, b->c+(q0-b->cq), m);
		q0 += m;
		s += m;
		n -= m;
	}
}

void
bufreset(Buffer *b)
{
	int i;

	b->nc = 0;
	b->cnc = 0;
	b->cq = 0;
	b->cdirty = 0;
	b->cbi = 0;
	/* delete backwards to avoid n² behavior */
	for(i=b->nbl-1; --i>=0; )
		delblock(b, i);
}

void
bufclose(Buffer *b)
{
	bufreset(b);
	free(b->c);
	b->c = nil;
	b->cnc = 0;
	free(b->bl);
	b->bl = nil;
	b->nbl = 0;
}
