#include <stdlib.h>
#ifdef _MSC_VER
#endif
#include <stdio.h>
#include <memory.h>
#include <assert.h>

#include <cn-cbor/cn-cbor.h>

#ifdef USE_CBOR_CONTEXT
#include "context.h"

typedef unsigned char byte;

typedef struct {
	cn_cbor_context context;
	byte *pFirst;
	ssize_t iFailLeft;
	ssize_t allocCount;
} MyContext;

typedef struct _MyItem {
	int allocNumber;
	struct _MyItem *pNext;
	size_t size;
	byte pad[4];
	byte data[4];
} MyItem;

bool CheckMemory(MyContext *pContext)
{
	MyItem *p = NULL;
	//  Walk memory and check every block

	for (p = (MyItem *)pContext->pFirst; p != NULL; p = p->pNext) {
		if (p->pad[0] == (byte)0xab) {
			//  Block has been freed
			for (unsigned i = 0; i < p->size + 8; i++) {
				if (p->pad[i] != (byte)0xab) {
					fprintf(stderr, "Freed block is modified");
					assert(false);
				}
			}
		}
		else if (p->pad[0] == (byte)0xef) {
			for (unsigned i = 0; i < 4; i++) {
				if ((p->pad[i] != (byte)0xef) || (p->pad[i + 4 + p->size] != (byte)0xef)) {
					fprintf(stderr, "Current block was overrun");
					assert(false);
				}
			}
		}
		else {
			fprintf(stderr, "Incorrect pad value");
			assert(false);
		}
	}

	return true;
}

void *MyCalloc(size_t count, size_t size, void *context)
{
	MyItem *pb = NULL;
	MyContext *myContext = (MyContext *)context;

	CheckMemory(myContext);

	if (myContext->iFailLeft != -1) {
		if (myContext->iFailLeft == 0) {
			return NULL;
		}
		myContext->iFailLeft--;
	}

	pb = (MyItem *)malloc(sizeof(MyItem) + count * size);

	memset(pb, 0xef, sizeof(MyItem) + count * size);
	memset(&pb->data, 0, count * size);

	pb->pNext = (struct _MyItem *)myContext->pFirst;
	myContext->pFirst = (byte *)pb;
	pb->size = count * size;
	pb->allocNumber = myContext->allocCount++;

	return &pb->data;
}

void MyFree(void *ptr, void *context)
{
	MyItem *pb = (MyItem *)((byte *)ptr - sizeof(MyItem) + 4);
	MyContext *myContext = (MyContext *)context;
	MyItem *pItem = NULL;

	CheckMemory(myContext);
	if (ptr == NULL) {
		return;
	}

	for (pItem = (MyItem *)myContext->pFirst; pItem != NULL; pItem = pItem->pNext) {
		if (pItem == pb) {
			break;
		}
	}

	if (pItem == NULL) {
		//  Not an item we allocated
		assert(false);
	}

	if (pb->pad[0] == 0xab) {
		// Item has already been freed
		assert(false);
	}

	memset(&pb->pad, 0xab, pb->size + 8);
}

cn_cbor_context *CreateContext(unsigned int iFailPoint)
{
	MyContext *p = malloc(sizeof(MyContext));

	p->context.calloc_func = MyCalloc;
	p->context.free_func = MyFree;
	p->context.context = p;
	p->pFirst = NULL;
	p->iFailLeft = iFailPoint;
	p->allocCount = 0;

	return &p->context;
}

void FreeContext(cn_cbor_context *pContext)
{
	MyContext *myContext = (MyContext *)pContext;
	MyItem *pItem;
	MyItem *pItem2;

	CheckMemory(myContext);

	for (pItem = (MyItem *)myContext->pFirst; pItem != NULL; pItem = pItem2) {
		pItem2 = pItem->pNext;
		free(pItem);
	}

	free(myContext);

	return;
}

int IsContextEmpty(const cn_cbor_context *pContext)
{
	MyContext *myContext = (MyContext *)pContext;
	MyItem *p;
	int i = 0;

	//  Walk memory and check every block

	for (p = (MyItem *)myContext->pFirst; p != NULL; p = p->pNext) {
		if (p->pad[0] == (byte)0xab) {
			//  Block has been freed
		}
		else {
			//  This block has not been freed
			i += 1;
		}
	}

	return i;
}

#endif	// USE_CBOR_CONTEXT
