#include <haproxy/ncbuf.h>

#include <string.h>

#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif

#ifdef STANDALONE
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include <haproxy/list.h>
#endif /* STANDALONE */

#ifdef DEBUG_DEV
# include <haproxy/bug.h>
#else
# include <stdio.h>
# include <stdlib.h>

# undef  BUG_ON
# define BUG_ON(x)     if (x) { fprintf(stderr, "CRASH ON %s:%d\n", __func__, __LINE__); abort(); }

# undef  BUG_ON_HOT
# define BUG_ON_HOT(x) if (x) { fprintf(stderr, "CRASH ON %s:%d\n", __func__, __LINE__); abort(); }
#endif /* DEBUG_DEV */

/* ******** internal API ******** */

#define NCB_BLK_NULL ((struct ncb_blk){ .st = NULL })

#define NCB_BK_F_GAP  0x01  /* block represents a gap */
#define NCB_BK_F_FIN  0x02  /* special reduced gap present at the end of the buffer */
struct ncb_blk {
	char *st;  /* first byte of the block */
	char *end; /* first byte after this block */

	char *sz_ptr; /* pointer to size element - NULL for reduced gap */
	ncb_sz_t sz; /* size of the block */
	ncb_sz_t sz_data; /* size of the data following the block - invalid for reduced GAP */
	ncb_sz_t off; /* offset of block in buffer */

	char flag;
};

/* Return pointer to <off> relative to <buf> head. Support buffer wrapping. */
static char *ncb_peek(const struct ncbuf *buf, ncb_sz_t off)
{
	char *ptr = ncb_head(buf) + off;
	if (ptr >= buf->area + buf->size)
		ptr -= buf->size;
	return ptr;
}

/* Returns the reserved space of <buf> which contains the size of the first
 * data block.
 */
static char *ncb_reserved(const struct ncbuf *buf)
{
	return ncb_peek(buf, buf->size - NCB_RESERVED_SZ);
}

/* Encode <off> at <st> position in <buf>. Support wrapping. */
static void ncb_write_off(const struct ncbuf *buf, char *st, ncb_sz_t off)
{
	int i;

	BUG_ON_HOT(st >= buf->area + buf->size);

	for (i = 0; i < sizeof(ncb_sz_t); ++i) {
		(*st) = off >> (8 * i) & 0xff;

		if ((++st) == ncb_wrap(buf))
			st = ncb_orig(buf);
	}
}

/* Decode offset stored at <st> position in <buf>. Support wrapping. */
static ncb_sz_t ncb_read_off(const struct ncbuf *buf, char *st)
{
	int i;
	ncb_sz_t off = 0;

	BUG_ON_HOT(st >= buf->area + buf->size);

	for (i = 0; i < sizeof(ncb_sz_t); ++i) {
		off |= (unsigned char )(*st) << (8 * i);

		if ((++st) == ncb_wrap(buf))
			st = ncb_orig(buf);
	}

	return off;
}

/* Add <off> to the offset stored at <st> in <buf>. Support wrapping. */
static void ncb_inc_off(const struct ncbuf *buf, char *st, ncb_sz_t off)
{
	const ncb_sz_t old = ncb_read_off(buf, st);
	ncb_write_off(buf, st, old + off);
}

/* Returns true if a gap cannot be inserted at <off> : a reduced gap must be used. */
static int ncb_off_reduced(const struct ncbuf *b, ncb_sz_t off)
{
	return off + NCB_GAP_MIN_SZ > ncb_size(b);
}

/* Returns true if <blk> is the special NULL block. */
static int ncb_blk_is_null(const struct ncb_blk blk)
{
	return !blk.st;
}

/* Returns true if <blk> is the last block of <buf>. */
static int ncb_blk_is_last(const struct ncbuf *buf, const struct ncb_blk blk)
{
	BUG_ON_HOT(blk.off + blk.sz > ncb_size(buf));
	return blk.off + blk.sz == ncb_size(buf);
}

/* Returns the first block of <buf> which is always a DATA. */
static struct ncb_blk ncb_blk_first(const struct ncbuf *buf)
{
	struct ncb_blk blk;

	if (ncb_is_null(buf))
		return NCB_BLK_NULL;

	blk.st = ncb_head(buf);

	blk.sz_ptr = ncb_reserved(buf);
	blk.sz = ncb_read_off(buf, ncb_reserved(buf));
	blk.sz_data = 0;
	BUG_ON_HOT(blk.sz > ncb_size(buf));

	blk.end = ncb_peek(buf, blk.sz);
	blk.off = 0;
	blk.flag = 0;

	return blk;
}

/* Returns the block following <prev> in the buffer <buf>. */
static struct ncb_blk ncb_blk_next(const struct ncbuf *buf,
                                   const struct ncb_blk prev)
{
	struct ncb_blk blk;

	BUG_ON_HOT(ncb_blk_is_null(prev));

	if (ncb_blk_is_last(buf, prev))
		return NCB_BLK_NULL;

	blk.st = prev.end;
	blk.off = prev.off + prev.sz;
	blk.flag = ~prev.flag & NCB_BK_F_GAP;

	if (blk.flag & NCB_BK_F_GAP) {
		if (ncb_off_reduced(buf, blk.off)) {
			blk.flag |= NCB_BK_F_FIN;
			blk.sz_ptr = NULL;
			blk.sz = ncb_size(buf) - blk.off;
			blk.sz_data = 0;

			/* A reduced gap can only be the last block. */
			BUG_ON_HOT(!ncb_blk_is_last(buf, blk));
		}
		else {
			blk.sz_ptr = ncb_peek(buf, blk.off + NCB_GAP_SZ_OFF);
			blk.sz = ncb_read_off(buf, blk.sz_ptr);
			blk.sz_data = ncb_read_off(buf, ncb_peek(buf, blk.off + NCB_GAP_SZ_DATA_OFF));
			BUG_ON_HOT(blk.sz < NCB_GAP_MIN_SZ);
		}
	}
	else {
		blk.sz_ptr = ncb_peek(buf, prev.off + NCB_GAP_SZ_DATA_OFF);
		blk.sz = prev.sz_data;
		blk.sz_data = 0;

		/* only first DATA block can be empty. If this happens, a GAP
		 * merge should have been realized.
		 */
		BUG_ON_HOT(!blk.sz);
	}

	BUG_ON_HOT(blk.off + blk.sz > ncb_size(buf));
	blk.end = ncb_peek(buf, blk.off + blk.sz);

	return blk;
}

/* Returns the block containing offset <off>. Note that if <off> is at the
 * frontier between two blocks, this function will return the preceding one.
 * This is done to easily merge blocks on insertion/deletion.
 */
static struct ncb_blk ncb_blk_find(const struct ncbuf *buf, ncb_sz_t off)
{
	struct ncb_blk blk;

	if (ncb_is_null(buf))
		return NCB_BLK_NULL;

	BUG_ON_HOT(off >= ncb_size(buf));

	for (blk = ncb_blk_first(buf); off > blk.off + blk.sz;
	     blk = ncb_blk_next(buf, blk)) {
	}

	return blk;
}

/* Transform absolute offset <off> to a relative one from <blk> start. */
static ncb_sz_t ncb_blk_off(const struct ncb_blk blk, ncb_sz_t off)
{
	BUG_ON_HOT(off < blk.off || off > blk.off + blk.sz);
	BUG_ON_HOT(off - blk.off > blk.sz);
	return off - blk.off;
}

/* Simulate insertion in <buf> of <data> of length <len> at offset <off>. This
 * ensures that minimal block size are respected for newly formed gaps. <blk>
 * must be the block where the insert operation begins. If <mode> is
 * NCB_ADD_COMPARE, old and new overlapped data are compared to validate the
 * insertion.
 *
 * Returns NCB_RET_OK if insertion can proceed.
 */
static enum ncb_ret ncb_check_insert(const struct ncbuf *buf,
                                     struct ncb_blk blk, ncb_sz_t off,
                                     const char *data, ncb_sz_t len,
                                     enum ncb_add_mode mode)
{
	ncb_sz_t off_blk = ncb_blk_off(blk, off);
	ncb_sz_t to_copy;
	ncb_sz_t left = len;

	/* If insertion starts in a gap, it must leave enough space to keep the
	 * gap header.
	 */
	if (left && (blk.flag & NCB_BK_F_GAP)) {
		if (off_blk < NCB_GAP_MIN_SZ)
			return NCB_RET_GAP_SIZE;
	}

	while (left) {
		off_blk = ncb_blk_off(blk, off);
		to_copy = MIN(left, blk.sz - off_blk);

		if (blk.flag & NCB_BK_F_GAP && off_blk + to_copy < blk.sz) {
			/* Insertion must leave enough space for a new gap
			 * header if stopped in a middle of a gap.
			 */
			const ncb_sz_t gap_sz = blk.sz - (off_blk + to_copy);
			if (gap_sz < NCB_GAP_MIN_SZ && !ncb_blk_is_last(buf, blk))
				return NCB_RET_GAP_SIZE;
		}
		else if (!(blk.flag & NCB_BK_F_GAP) && mode == NCB_ADD_COMPARE) {
			/* Compare memory of data block in NCB_ADD_COMPARE mode. */
			const ncb_sz_t off_blk = ncb_blk_off(blk, off);
			char *st = ncb_peek(buf, off);

			to_copy = MIN(left, blk.sz - off_blk);
			if (st + to_copy > ncb_wrap(buf)) {
				const ncb_sz_t sz1 = ncb_wrap(buf) - st;
				if (memcmp(st, data, sz1))
					return NCB_RET_DATA_REJ;
				if (memcmp(ncb_orig(buf), data + sz1, to_copy - sz1))
					return NCB_RET_DATA_REJ;
			}
			else {
				if (memcmp(st, data, to_copy))
					return NCB_RET_DATA_REJ;
			}
		}

		left -= to_copy;
		data += to_copy;
		off  += to_copy;

		blk = ncb_blk_next(buf, blk);
	}

	return NCB_RET_OK;
}

/* Fill new <data> of length <len> inside an already existing data <blk> at
 * offset <off>. Offset is relative to <blk> so it cannot be greater than the
 * block size. <mode> specifies if old data are preserved or overwritten.
 */
static ncb_sz_t ncb_fill_data_blk(const struct ncbuf *buf,
                                  struct ncb_blk blk, ncb_sz_t off,
                                  const char *data, ncb_sz_t len,
                                  enum ncb_add_mode mode)
{
	const ncb_sz_t to_copy = MIN(len, blk.sz - off);
	char *ptr = NULL;

	BUG_ON_HOT(off > blk.sz);
	/* This can happens due to previous ncb_blk_find() usage. In this
	 * case the current fill is a noop.
	 */
	if (off == blk.sz)
		return 0;

	if (mode == NCB_ADD_OVERWRT) {
		ptr = ncb_peek(buf, blk.off + off);

		if (ptr + to_copy >= ncb_wrap(buf)) {
			const ncb_sz_t sz1 = ncb_wrap(buf) - ptr;
			memcpy(ptr, data, sz1);
			memcpy(ncb_orig(buf), data + sz1, to_copy - sz1);
		}
		else {
			memcpy(ptr, data, to_copy);
		}
	}

	return to_copy;
}

/* Fill the gap <blk> starting at <off> with new <data> of length <len>. <off>
 * is relative to <blk> so it cannot be greater than the block size.
 */
static ncb_sz_t ncb_fill_gap_blk(const struct ncbuf *buf,
                                 struct ncb_blk blk, ncb_sz_t off,
                                 const char *data, ncb_sz_t len)
{
	const ncb_sz_t to_copy = MIN(len, blk.sz - off);
	char *ptr;

	BUG_ON_HOT(off > blk.sz);
	/* This can happens due to previous ncb_blk_find() usage. In this
	 * case the current fill is a noop.
	 */
	if (off == blk.sz)
		return 0;

	/* A new gap must be created if insertion stopped before gap end. */
	if (off + to_copy < blk.sz) {
		const ncb_sz_t gap_off = blk.off + off + to_copy;
		const ncb_sz_t gap_sz = blk.sz - off - to_copy;

		BUG_ON_HOT(!ncb_off_reduced(buf, gap_off) &&
		           blk.off + blk.sz - gap_off < NCB_GAP_MIN_SZ);

		/* write the new gap header unless this is a reduced gap. */
		if (!ncb_off_reduced(buf, gap_off)) {
			char *gap_ptr = ncb_peek(buf, gap_off + NCB_GAP_SZ_OFF);
			char *gap_data_ptr = ncb_peek(buf, gap_off + NCB_GAP_SZ_DATA_OFF);

			ncb_write_off(buf, gap_ptr, gap_sz);
			ncb_write_off(buf, gap_data_ptr, blk.sz_data);
		}
	}

	/* fill the gap with new data */
	ptr = ncb_peek(buf, blk.off + off);
	if (ptr + to_copy >= ncb_wrap(buf)) {
		ncb_sz_t sz1 = ncb_wrap(buf) - ptr;
		memcpy(ptr, data, sz1);
		memcpy(ncb_orig(buf), data + sz1, to_copy - sz1);
	}
	else {
		memcpy(ptr, data, to_copy);
	}

	return to_copy;
}

/* ******** public API ******** */

int ncb_is_null(const struct ncbuf *buf)
{
	return buf->size == 0;
}

/* Initialize or reset <buf> by clearing all data. Its size is untouched.
 * Buffer is positioned to <head> offset. Use 0 to realign it. <buf> must not
 * be NCBUF_NULL.
 */
void ncb_init(struct ncbuf *buf, ncb_sz_t head)
{
	BUG_ON_HOT(ncb_is_null(buf));

	BUG_ON_HOT(head >= buf->size);
	buf->head = head;

	ncb_write_off(buf, ncb_reserved(buf), 0);
	ncb_write_off(buf, ncb_head(buf), ncb_size(buf));
	ncb_write_off(buf, ncb_peek(buf, sizeof(ncb_sz_t)), 0);
}

/* Construct a ncbuf with all its parameters. */
struct ncbuf ncb_make(char *area, ncb_sz_t size, ncb_sz_t head)
{
	struct ncbuf buf;

	/* Ensure that there is enough space for the reserved space and data.
	 * This is the minimal value to not crash later.
	 */
	BUG_ON_HOT(size <= NCB_RESERVED_SZ);

	buf.area = area;
	buf.size = size;
	buf.head = head;

	return buf;
}

/* Returns start of allocated buffer area. */
char *ncb_orig(const struct ncbuf *buf)
{
	return buf->area;
}

/* Returns current head pointer into buffer area. */
char *ncb_head(const struct ncbuf *buf)
{
	return buf->area + buf->head;
}

/* Returns the first byte after the allocated buffer area. */
char *ncb_wrap(const struct ncbuf *buf)
{
	return buf->area + buf->size;
}

/* Returns the usable size of <buf> for data storage. This is the size of the
 * allocated buffer without the reserved header space.
 */
ncb_sz_t ncb_size(const struct ncbuf *buf)
{
	if (ncb_is_null(buf))
		return 0;

	return buf->size - NCB_RESERVED_SZ;
}

/* Returns the total number of bytes stored in whole <buf>. */
ncb_sz_t ncb_total_data(const struct ncbuf *buf)
{
	struct ncb_blk blk;
	int total = 0;

	for (blk = ncb_blk_first(buf); !ncb_blk_is_null(blk); blk = ncb_blk_next(buf, blk)) {
		if (!(blk.flag & NCB_BK_F_GAP))
			total += blk.sz;
	}

	return total;
}

/* Returns true if there is no data anywhere in <buf>. */
int ncb_is_empty(const struct ncbuf *buf)
{
	int first_data, first_gap;

	if (ncb_is_null(buf))
		return 1;

	first_data = ncb_read_off(buf, ncb_reserved(buf));
	BUG_ON_HOT(first_data > ncb_size(buf));
	/* Buffer is not empty if first data block is not nul. */
	if (first_data)
		return 0;

	/* Head contains the first gap size if first data block is empty. */
	first_gap  = ncb_read_off(buf, ncb_head(buf));
	BUG_ON_HOT(first_gap > ncb_size(buf));
	return first_gap == ncb_size(buf);
}

/* Returns true if no more data can be inserted in <buf>. */
int ncb_is_full(const struct ncbuf *buf)
{
	int first_data;

	if (ncb_is_null(buf))
		return 0;

	/* First data block must cover whole buffer if full. */
	first_data = ncb_read_off(buf, ncb_reserved(buf));
	BUG_ON_HOT(first_data > ncb_size(buf));
	return first_data == ncb_size(buf);
}

/* Returns the number of bytes of data avaiable in <buf> starting at offset
 * <off> until the next gap or the buffer end. The counted data may wrapped if
 * the buffer storage is not aligned.
 */
ncb_sz_t ncb_data(const struct ncbuf *buf, ncb_sz_t off)
{
	struct ncb_blk blk;
	ncb_sz_t off_blk;

	if (ncb_is_null(buf))
		return 0;

	blk = ncb_blk_find(buf, off);
	off_blk = ncb_blk_off(blk, off);

	/* if <off> at the frontier between two and <blk> is gap, retrieve the
	 * next data block.
	 */
	if (blk.flag & NCB_BK_F_GAP && off_blk == blk.sz &&
	    !ncb_blk_is_last(buf, blk)) {
		blk = ncb_blk_next(buf, blk);
		off_blk = ncb_blk_off(blk, off);
	}

	if (blk.flag & NCB_BK_F_GAP)
		return 0;

	return blk.sz - off_blk;
}

/* Add a new block at <data> of size <len> in <buf> at offset <off>.
 *
 * Returns NCB_RET_OK on success. On error the following codes are returned :
 * - NCB_RET_GAP_SIZE : cannot add data because the gap formed is too small
 * - NCB_RET_DATA_REJ : old data would be overwritten by different ones in
 *                      NCB_ADD_COMPARE mode.
 */
enum ncb_ret ncb_add(struct ncbuf *buf, ncb_sz_t off,
                     const char *data, ncb_sz_t len, enum ncb_add_mode mode)
{
	struct ncb_blk blk;
	ncb_sz_t left = len;
	enum ncb_ret ret;
	char *new_sz;

	if (!len)
		return NCB_RET_OK;

	BUG_ON_HOT(off + len > ncb_size(buf));

	/* Get block where insertion begins. */
	blk = ncb_blk_find(buf, off);

	/* Check if insertion is possible. */
	ret = ncb_check_insert(buf, blk, off, data, len, mode);
	if (ret != NCB_RET_OK)
		return ret;

	if (blk.flag & NCB_BK_F_GAP) {
		/* Reduce gap size if insertion begins in a gap. Gap data size
		 * is reset and will be recalculated during insertion.
		 */
		const ncb_sz_t gap_sz = off - blk.off;
		BUG_ON_HOT(gap_sz < NCB_GAP_MIN_SZ);

		/* pointer to data size to increase. */
		new_sz = ncb_peek(buf, blk.off + NCB_GAP_SZ_DATA_OFF);

		ncb_write_off(buf, blk.sz_ptr, gap_sz);
		ncb_write_off(buf, new_sz, 0);
	}
	else {
		/* pointer to data size to increase. */
		new_sz = blk.sz_ptr;
	}

	/* insert data */
	while (left) {
		struct ncb_blk next;
		const ncb_sz_t off_blk = ncb_blk_off(blk, off);
		ncb_sz_t done;

		/* retrieve the next block. This is necessary to do this
		 * before overwritting a gap.
		 */
		next = ncb_blk_next(buf, blk);

		if (blk.flag & NCB_BK_F_GAP) {
			done = ncb_fill_gap_blk(buf, blk, off_blk, data, left);

			/* update the inserted data block size */
			if (off + done == blk.off + blk.sz) {
				/* merge next data block if insertion reached gap end */
				ncb_inc_off(buf, new_sz, done + blk.sz_data);
			}
			else {
				/* insertion stopped before gap end */
				ncb_inc_off(buf, new_sz, done);
			}
		}
		else {
			done = ncb_fill_data_blk(buf, blk, off_blk, data, left, mode);
		}

		BUG_ON_HOT(done > blk.sz || done > left);
		left -= done;
		data += done;
		off  += done;

		blk = next;
	}

	return NCB_RET_OK;
}

/* Advance the head of <buf> to the offset <adv>. Data at the start of buffer
 * will be lost while some space will be formed at the end to be able to insert
 * new data.
 *
 * Returns NCB_RET_OK on success.
 */
enum ncb_ret ncb_advance(struct ncbuf *buf, ncb_sz_t adv)
{
	struct ncb_blk start, last;
	ncb_sz_t off_blk;
	ncb_sz_t first_data_sz;

	BUG_ON_HOT(adv > ncb_size(buf));
	if (!adv)
		return NCB_RET_OK;

	/* Special case if adv is full size. This is equivalent to a reset. */
	if (adv == ncb_size(buf)) {
		ncb_init(buf, buf->head);
		return NCB_RET_OK;
	}

	start = ncb_blk_find(buf, adv);

	/* Special case if advance until the last block which is a GAP. The
	 * buffer will be left empty and is thus equivalent to a reset.
	 */
	if (ncb_blk_is_last(buf, start) && (start.flag & NCB_BK_F_GAP)) {
		ncb_sz_t new_head = buf->head + adv;
		if (new_head >= buf->size)
			new_head -= buf->size;

		ncb_init(buf, new_head);
		return NCB_RET_OK;
	}

	last = start;
	while (!ncb_blk_is_last(buf, last))
		last = ncb_blk_next(buf, last);

	off_blk = ncb_blk_off(start, adv);

	if (start.flag & NCB_BK_F_GAP) {
		/* If advance in a GAP, its new size must be big enough. */
		if (start.sz == off_blk) {
			/* GAP removed. Buffer will start with following DATA block. */
			first_data_sz = start.sz_data;
		}
		else if (start.sz - off_blk < NCB_GAP_MIN_SZ) {
			return NCB_RET_GAP_SIZE;
		}
		else {
			/* Buffer will start with this GAP block. */
			first_data_sz = 0;
		}
	}
	else {
		/* If off_blk less than start.sz, the data block will becomes the
		 * first block. If equal, the data block is completely removed
		 * and thus the following GAP will be the first block.
		 */
		first_data_sz = start.sz - off_blk;
	}

	if (last.flag & NCB_BK_F_GAP) {
		/* Extend last GAP unless this is a reduced gap. */
		if (!(last.flag & NCB_BK_F_FIN) || last.sz + adv >= NCB_GAP_MIN_SZ) {
			/* use .st instead of .sz_ptr which can be NULL if reduced gap */
			ncb_write_off(buf, last.st, last.sz + adv);
			ncb_write_off(buf, ncb_peek(buf, last.off + NCB_GAP_SZ_DATA_OFF), 0);
		}
	}
	else {
		/* Insert a GAP after the last DATA block. */
		if (adv >= NCB_GAP_MIN_SZ) {
			ncb_write_off(buf, ncb_peek(buf, last.off + last.sz + NCB_GAP_SZ_OFF), adv);
			ncb_write_off(buf, ncb_peek(buf, last.off + last.sz + NCB_GAP_SZ_DATA_OFF), 0);
		}
	}

	/* Advance head and update reserved header with new first data size. */
	buf->head += adv;
	if (buf->head >= buf->size)
		buf->head -= buf->size;
	ncb_write_off(buf, ncb_reserved(buf), first_data_sz);

	/* If advance in a GAP, reduce its size. */
	if (start.flag & NCB_BK_F_GAP && !first_data_sz) {
		ncb_write_off(buf, ncb_head(buf), start.sz - off_blk);
		/* Recopy the block sz_data at the new position. */
		ncb_write_off(buf, ncb_peek(buf, NCB_GAP_SZ_DATA_OFF), start.sz_data);
	}

	return NCB_RET_OK;
}

/* ******** testing API ******** */
/* To build it :
 *   gcc -Wall -DSTANDALONE -lasan -I./include -o ncbuf src/ncbuf.c
 */
#ifdef STANDALONE

int ncb_print = 0;

static void ncbuf_printf(char *str, ...)
{
	va_list args;

	va_start(args, str);
	if (ncb_print)
		vfprintf(stderr, str, args);
	va_end(args);
}

struct rand_off {
	struct list el;
	ncb_sz_t off;
	ncb_sz_t len;
};

static struct rand_off *ncb_generate_rand_off(const struct ncbuf *buf)
{
	struct rand_off *roff;
	roff = calloc(1, sizeof(*roff));
	BUG_ON(!roff);

	roff->off = rand() % (ncb_size(buf));
	if (roff->off > 0 && roff->off < NCB_GAP_MIN_SZ)
		roff->off = 0;

	roff->len = rand() % (ncb_size(buf) - roff->off + 1);

	return roff;
}

static void ncb_print_blk(const struct ncb_blk blk)
{
	if (ncb_print) {
		fprintf(stderr, "%s(%s): %2u/%u.\n",
		        blk.flag & NCB_BK_F_GAP ? "GAP " : "DATA",
		        blk.flag & NCB_BK_F_FIN ? "F" : "-", blk.off, blk.sz);
	}
}

static inline int ncb_is_null_blk(const struct ncb_blk blk)
{
	return !blk.st;
}

static void ncb_loop(const struct ncbuf *buf)
{
	struct ncb_blk blk;

	blk = ncb_blk_first(buf);
	do {
		ncb_print_blk(blk);
		blk = ncb_blk_next(buf, blk);
	} while (!ncb_is_null_blk(blk));

	ncbuf_printf("\n");
}

static void ncbuf_print_buf(struct ncbuf *b, ncb_sz_t len,
                            unsigned char *area, int line)
{
	int i;

	ncbuf_printf("buffer status at line %d\n", line);
	for (i = 0; i < len; ++i) {
		ncbuf_printf("%02x.", area[i]);
		if (i && i % 32 == 31)    ncbuf_printf("\n");
		else if (i && i % 8 == 7) ncbuf_printf(" ");
	}
	ncbuf_printf("\n");

	ncb_loop(b);

	if (ncb_print)
		getchar();
}

static struct ncbuf b;
static unsigned char *bufarea = NULL;
static ncb_sz_t bufsize = 16384;
static ncb_sz_t bufhead = 15;

#define NCB_INIT(buf) \
  if ((reset)) { memset(bufarea, 0xaa, bufsize); } \
  ncb_init(buf, bufhead); \
  ncbuf_print_buf(&b, bufsize, bufarea, __LINE__);

#define NCB_ADD_EQ(buf, off, data, sz, mode, ret) \
  BUG_ON(ncb_add((buf), (off), (data), (sz), (mode)) != (ret)); \
  ncbuf_print_buf(buf, bufsize, bufarea, __LINE__);

#define NCB_ADD_NEQ(buf, off, data, sz, mode, ret) \
  BUG_ON(ncb_add((buf), (off), (data), (sz), (mode)) == (ret)); \
  ncbuf_print_buf(buf, bufsize, bufarea, __LINE__);

#define NCB_ADVANCE_EQ(buf, off, ret) \
  BUG_ON(ncb_advance((buf), (off)) != (ret)); \
  ncbuf_print_buf(buf, bufsize, bufarea, __LINE__);

#define NCB_TOTAL_DATA_EQ(buf, data) \
  BUG_ON(ncb_total_data((buf)) != (data));

#define NCB_DATA_EQ(buf, off, data) \
  BUG_ON(ncb_data((buf), (off)) != (data));

static int ncbuf_test(ncb_sz_t head, int reset, int print_delay)
{
	char *data0, data1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
	struct list list = LIST_HEAD_INIT(list);
	struct rand_off *roff, *roff_tmp;
	enum ncb_ret ret;

	data0 = malloc(bufsize);
	memset(data0, 0xff, bufsize);

	bufarea = malloc(bufsize);

	fprintf(stderr, "running unit tests\n");

	b = NCBUF_NULL;
	BUG_ON(!ncb_is_null(&b));
	NCB_DATA_EQ(&b, 0, 0);
	NCB_TOTAL_DATA_EQ(&b, 0);
	BUG_ON(ncb_size(&b) != 0);
	BUG_ON(!ncb_is_empty(&b));
	BUG_ON(ncb_is_full(&b));

	b.area = (char *)bufarea;
	b.size = bufsize;
	b.head = head;
	NCB_INIT(&b);

	/* insertion test suite */
	NCB_INIT(&b);
	NCB_DATA_EQ(&b, 0, 0); NCB_DATA_EQ(&b, bufsize - NCB_RESERVED_SZ - 1, 0); /* first and last offset */
	NCB_ADD_EQ(&b, 24, data0,  9, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 24,  9);
	/* insert new data at the same offset as old */
	NCB_ADD_EQ(&b, 24, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 24, 16);

	NCB_INIT(&b); NCB_DATA_EQ(&b, 0, 0);
	NCB_ADD_EQ(&b,  0, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16);
	NCB_ADD_EQ(&b, 24, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16);
	/* insert data overlapping two data blocks and a gap */
	NCB_ADD_EQ(&b, 12, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 40);

	NCB_INIT(&b);
	NCB_ADD_EQ(&b, 32, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0,  0); NCB_DATA_EQ(&b, 16,  0); NCB_DATA_EQ(&b, 32, 16);
	NCB_ADD_EQ(&b,  0, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16); NCB_DATA_EQ(&b, 16,  0); NCB_DATA_EQ(&b, 32, 16);
	/* insert data to exactly cover a gap between two data blocks */
	NCB_ADD_EQ(&b, 16, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 48); NCB_DATA_EQ(&b, 16, 32); NCB_DATA_EQ(&b, 32, 16);

	NCB_INIT(&b);
	NCB_ADD_EQ(&b, 0,  data0, 8, NCB_ADD_PRESERVE, NCB_RET_OK);
	/* this insertion must be rejected because of minimal gap size */
	NCB_ADD_EQ(&b, 10, data0, 8, NCB_ADD_PRESERVE, NCB_RET_GAP_SIZE);

	/* Test reduced gap support */
	NCB_INIT(&b);
	/* this insertion will form a reduced gap */
	NCB_ADD_EQ(&b, 0, data0, bufsize - (NCB_GAP_MIN_SZ - 1), NCB_ADD_COMPARE, NCB_RET_OK);

	/* Test the various insertion mode */
	NCB_INIT(&b);
	NCB_ADD_EQ(&b, 10, data1, 16, NCB_ADD_PRESERVE, NCB_RET_OK);
	NCB_ADD_EQ(&b, 12, data1, 16, NCB_ADD_COMPARE,  NCB_RET_DATA_REJ);
	NCB_ADD_EQ(&b, 12, data1, 16, NCB_ADD_PRESERVE, NCB_RET_OK); BUG_ON(*ncb_peek(&b, 12) != data1[2]);
	NCB_ADD_EQ(&b, 12, data1, 16, NCB_ADD_OVERWRT,  NCB_RET_OK); BUG_ON(*ncb_peek(&b, 12) == data1[2]);

	/* advance test suite */
	NCB_INIT(&b);
	NCB_ADVANCE_EQ(&b, 10, NCB_RET_OK); /* advance in an empty buffer; this ensures we do not leave an empty DATA in the middle of the buffer */
	NCB_ADVANCE_EQ(&b, ncb_size(&b) - 2, NCB_RET_OK);

	NCB_INIT(&b);
	/* first fill the buffer */
	NCB_ADD_EQ(&b, 0, data0, bufsize - NCB_RESERVED_SZ, NCB_ADD_COMPARE, NCB_RET_OK);
	/* delete 2 bytes : a reduced gap must be created */
	NCB_ADVANCE_EQ(&b, 2, NCB_RET_OK); NCB_TOTAL_DATA_EQ(&b, ncb_size(&b) - 2);
	/* delete 1 byte : extend the reduced gap */
	NCB_ADVANCE_EQ(&b, 1, NCB_RET_OK); NCB_TOTAL_DATA_EQ(&b, ncb_size(&b) - 3);
	/* delete 5 bytes : a full gap must be present */
	NCB_ADVANCE_EQ(&b, 5, NCB_RET_OK); NCB_TOTAL_DATA_EQ(&b, ncb_size(&b) - 8);
	/* completely clear the buffer */
	NCB_ADVANCE_EQ(&b, bufsize - NCB_RESERVED_SZ, NCB_RET_OK); NCB_TOTAL_DATA_EQ(&b, 0);


	NCB_INIT(&b);
	NCB_ADD_EQ(&b, 10, data0, 10, NCB_ADD_PRESERVE, NCB_RET_OK);
	NCB_ADVANCE_EQ(&b,  2, NCB_RET_OK); /* reduce a gap in front of the buffer */
	NCB_ADVANCE_EQ(&b,  1, NCB_RET_GAP_SIZE); /* reject */
	NCB_ADVANCE_EQ(&b,  8, NCB_RET_OK); /* remove completely the gap */
	NCB_ADVANCE_EQ(&b,  8, NCB_RET_OK); /* remove inside the data */
	NCB_ADVANCE_EQ(&b, 10, NCB_RET_OK); /* remove completely the data */

	fprintf(stderr, "first random pass\n");
	NCB_INIT(&b);

	/* generate randon data offsets until the buffer is full */
	while (!ncb_is_full(&b)) {
		roff = ncb_generate_rand_off(&b);
		LIST_INSERT(&list, &roff->el);

		ret = ncb_add(&b, roff->off, data0, roff->len, NCB_ADD_COMPARE);
		BUG_ON(ret == NCB_RET_DATA_REJ);
		ncbuf_print_buf(&b, bufsize, bufarea, __LINE__);
		usleep(print_delay);
	}

	fprintf(stderr, "buf full, prepare for reverse random\n");
	ncbuf_print_buf(&b, bufsize, bufarea, __LINE__);

	/* insert the previously generated random offsets in the reverse order.
	 * At the end, the buffer should be full.
	 */
	NCB_INIT(&b);
	list_for_each_entry_safe(roff, roff_tmp, &list, el) {
		int full = ncb_is_full(&b);
		if (!full) {
			ret = ncb_add(&b, roff->off, data0, roff->len, NCB_ADD_COMPARE);
			BUG_ON(ret == NCB_RET_DATA_REJ);
			ncbuf_print_buf(&b, bufsize, bufarea, __LINE__);
			usleep(print_delay);
		}

		LIST_DELETE(&roff->el);
		free(roff);
	}

	if (!ncb_is_full(&b))
		abort();

	fprintf(stderr, "done\n");

	free(bufarea);
	free(data0);

	return 1;
}

int main(int argc, char **argv)
{
	int reset = 0;
	int print_delay = 100000;
	char c;

	opterr = 0;
	while ((c = getopt(argc, argv, "h:s:rp::")) != -1) {
		switch (c) {
		case 'h':
			bufhead = atoi(optarg);
			break;
		case 's':
			bufsize = atoi(optarg);
			if (bufsize < 64) {
				fprintf(stderr, "bufsize should be at least 64 bytes for unit test suite\n");
				exit(127);
			}
			break;
		case 'r':
			reset = 1;
			break;
		case 'p':
			if (optarg)
				print_delay = atoi(optarg);
			ncb_print = 1;
			break;
		case '?':
		default:
			fprintf(stderr, "usage: %s [-r] [-s bufsize] [-h bufhead] [-p <delay_msec>]\n", argv[0]);
			exit(127);
		}
	}

	ncbuf_test(bufhead, reset, print_delay);
	return EXIT_SUCCESS;
}

#endif /* STANDALONE */
