#ifdef __cplusplus
extern "C" {
#endif
#ifdef EMACS_INDENTATION_HELPER
} /* Duh. */
#endif

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#ifdef _MSC_VER
#include <WinSock2.h>  // needed for ntohl on Windows
#else
#ifndef __MBED__
#include <arpa/inet.h>	// needed for ntohl (e.g.) on Linux
#endif

#include "dll-export.h"
#endif	// _MSC_VER

#include "cn-cbor/cn-cbor.h"
#include "cbor.h"

#define CN_CBOR_FAIL(code) \
	do {                   \
		pb->err = code;    \
		goto fail;         \
	} while (0)

CN_CBOR_EXPORT
void cn_cbor_dont_free_data(cn_cbor *cbor)
{
	cbor->flags |= CN_CBOR_FL_EXT_DATA;
}

CN_CBOR_EXPORT
void cn_cbor_free(cn_cbor *cb CBOR_CONTEXT)
{
	cn_cbor *p = (cn_cbor *)cb;
	assert(!p || !p->parent);
	while (p) {
		cn_cbor *p1;
		while ((p1 = p->first_child)) { /* go down */
			p = p1;
		}
		if (!(p1 = p->next)) { /* go up next */
			if ((p1 = p->parent)) {
				p1->first_child = 0;
			}
		}

		if ((p->flags & CN_CBOR_FL_EXT_DATA) == 0) {
			switch (p->type) {
				case CN_CBOR_BYTES:
				case CN_CBOR_TEXT:
					CN_CBOR_FREE_CONTEXT((void *) p->v.bytes);
					break;

				default:
					break;
			}
		}
		if ((p->flags & CN_CBOR_FL_EXT_SELF) == 0) {
			CN_CBOR_FREE_CONTEXT(p);
		}
		p = p1;
	}
}

#ifndef CBOR_NO_FLOAT
static double decode_half(int half)
{
	int exp = (half >> 10) & 0x1f;
	int mant = half & 0x3ff;
	double val;
	if (exp == 0) {
		val = ldexp(mant, -24);
	}
	else if (exp != 31) {
		val = ldexp(mant + 1024, exp - 25);
	}
	else {
		val = mant == 0 ? INFINITY : NAN;
	}
	return half & 0x8000 ? -val : val;
}
#endif /* CBOR_NO_FLOAT */

#define ntoh8p(p) (*(unsigned char *)(p))

#ifndef CBOR_ALIGN_READS
#define ntoh16p(p) (ntohs(*(unsigned short *)(p)))
#define ntoh32p(p) (ntohl(*(unsigned long *)(p)))
#else
static uint16_t ntoh16p(unsigned char *p)
{
	uint16_t tmp;
	memcpy(&tmp, p, sizeof(tmp));
	return ntohs(tmp);
}

static uint32_t ntoh32p(unsigned char *p)
{
	uint32_t tmp;
	memcpy(&tmp, p, sizeof(tmp));
	return ntohl(tmp);
}
#endif /* CBOR_ALIGN_READS */

static uint64_t ntoh64p(unsigned char *p)
{
	uint64_t ret = ntoh32p(p);
	ret <<= 32;
	ret += ntoh32p(p + 4);
	return ret;
}

static cn_cbor_type mt_trans[] = {
	CN_CBOR_UINT,
	CN_CBOR_INT,
	CN_CBOR_BYTES,
	CN_CBOR_TEXT,
	CN_CBOR_ARRAY,
	CN_CBOR_MAP,
	CN_CBOR_TAG,
	CN_CBOR_SIMPLE,
};

struct parse_buf {
	unsigned char *buf;
	unsigned char *ebuf;
	cn_cbor_error err;
};

#define TAKE(pos, ebuf, n, stmt)               \
	if ((n) > (size_t)((ebuf) - (pos)))          \
		CN_CBOR_FAIL(CN_CBOR_ERR_OUT_OF_DATA); \
	stmt;                                      \
	(pos) += (n);

static cn_cbor *decode_item(struct parse_buf *pb CBOR_CONTEXT, cn_cbor *top_parent)
{
	unsigned char *pos = pb->buf;
	unsigned char *ebuf = pb->ebuf;
	cn_cbor *parent = top_parent;
	int ib = 0;
	unsigned int mt = 0;
	int ai = 0;
	uint64_t val = 0;
	cn_cbor *cb = NULL;
#ifndef CBOR_NO_FLOAT
	union {
		float f;
		uint32_t u;
	} u32;
	union {
		double d;
		uint64_t u;
	} u64;
#endif /* CBOR_NO_FLOAT */

again:
	TAKE(pos, ebuf, 1, ib = ntoh8p(pos));
	if (ib == IB_BREAK) {
		if (!(parent->flags & CN_CBOR_FL_INDEF)) {
			CN_CBOR_FAIL(CN_CBOR_ERR_BREAK_OUTSIDE_INDEF);
		}
		switch (parent->type) {
			case CN_CBOR_BYTES:
			case CN_CBOR_TEXT:
				parent->type += 2; /* CN_CBOR_* -> CN_CBOR_*_CHUNKED */
				break;

			case CN_CBOR_MAP:
				if (parent->length & 1) {
					CN_CBOR_FAIL(CN_CBOR_ERR_ODD_SIZE_INDEF_MAP);
				}
				break;

			case CN_CBOR_ARRAY:
				break;

			default:
				CN_CBOR_FAIL(CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING);
		}
		goto complete;
	}
	mt = ib >> 5;
	ai = ib & 0x1f;
	val = ai;

	cb = CN_CALLOC_CONTEXT();
	if (!cb) {
		CN_CBOR_FAIL(CN_CBOR_ERR_OUT_OF_MEMORY);
	}

	cb->type = mt_trans[mt];

	cb->parent = parent;
	if (parent->last_child) {
		parent->last_child->next = cb;
	}
	else {
		parent->first_child = cb;
	}
	parent->last_child = cb;
	parent->length++;

	switch (ai) {
		case AI_1:
			TAKE(pos, ebuf, 1, val = ntoh8p(pos));
			break;
		case AI_2:
			TAKE(pos, ebuf, 2, val = ntoh16p(pos));
			break;
		case AI_4:
			TAKE(pos, ebuf, 4, val = ntoh32p(pos));
			break;
		case AI_8:
			TAKE(pos, ebuf, 8, val = ntoh64p(pos));
			break;
		case 28:
		case 29:
		case 30:
			CN_CBOR_FAIL(CN_CBOR_ERR_RESERVED_AI);
		case AI_INDEF:
			if ((mt - MT_BYTES) <= MT_MAP) {
				cb->flags |= CN_CBOR_FL_INDEF;
				goto push;
			}
			else {
				CN_CBOR_FAIL(CN_CBOR_ERR_MT_UNDEF_FOR_INDEF);
			}
		default:
			break;
	}

	// process content
	switch (mt) {
		case MT_UNSIGNED:
			cb->v.uint = val; /* to do: Overflow check */
			break;
		case MT_NEGATIVE:
			cb->v.sint = ~val; /* to do: Overflow check */
			break;
		case MT_BYTES:
		case MT_TEXT:
			cb->v.str = (char *)pos;
			cb->length = (size_t)val;
			cb->flags |= CN_CBOR_FL_EXT_DATA;
			TAKE(pos, ebuf, val, ;);
			break;
		case MT_MAP:
			val <<= 1;
			/* fall through */
		case MT_ARRAY:
			if ((cb->v.count = val)) {
				cb->flags |= CN_CBOR_FL_COUNT;
				goto push;
			}
			break;
		case MT_TAG:
			cb->v.uint = val;
			goto push;
		case MT_PRIM:
			switch (ai) {
				case VAL_FALSE:
					cb->type = CN_CBOR_FALSE;
					break;
				case VAL_TRUE:
					cb->type = CN_CBOR_TRUE;
					break;
				case VAL_NIL:
					cb->type = CN_CBOR_NULL;
					break;
				case VAL_UNDEF:
					cb->type = CN_CBOR_UNDEF;
					break;
				case AI_2:
#ifndef CBOR_NO_FLOAT
					cb->type = CN_CBOR_DOUBLE;
					cb->v.dbl = decode_half((int) val);
#else  /*  CBOR_NO_FLOAT */
					CN_CBOR_FAIL(CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
#endif /*  CBOR_NO_FLOAT */
					break;
				case AI_4:
#ifndef CBOR_NO_FLOAT
					cb->type = CN_CBOR_DOUBLE;
					u32.u = (uint32_t)val;
					cb->v.dbl = u32.f;
#else  /*  CBOR_NO_FLOAT */
					CN_CBOR_FAIL(CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
#endif /*  CBOR_NO_FLOAT */
					break;
				case AI_8:
#ifndef CBOR_NO_FLOAT
					cb->type = CN_CBOR_DOUBLE;
					u64.u = val;
					cb->v.dbl = u64.d;
#else  /*  CBOR_NO_FLOAT */
					CN_CBOR_FAIL(CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
#endif /*  CBOR_NO_FLOAT */
					break;
				default:
					cb->v.uint = val;
					if (24 <= val && val < 32) {
						CN_CBOR_FAIL(CN_CBOR_ERR_INVALID_PARAMETER);
					}
					break;
			}
			break;

		default:
			CN_CBOR_FAIL(CN_CBOR_ERR_INVALID_PARAMETER);
	}

fill: /* emulate loops */
	if (parent->flags & CN_CBOR_FL_INDEF) {
		if (parent->type == CN_CBOR_BYTES || parent->type == CN_CBOR_TEXT) {
			if (cb->type != parent->type) {
				CN_CBOR_FAIL(CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING);
			}
		}
		goto again;
	}
	if (parent->flags & CN_CBOR_FL_COUNT) {
		if (--parent->v.count) {
			goto again;
		}
	}
	/* so we are done filling parent. */
complete: /* emulate return from call */
	if (parent == top_parent) {
		if (pos != ebuf) {
			/* XXX do this outside */
			CN_CBOR_FAIL(CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED);
		}
		pb->buf = pos;
		return cb;
	}
	cb = parent;
	parent = parent->parent;
	goto fill;
push: /* emulate recursive call */
	parent = cb;
	goto again;
fail:
	pb->buf = pos;
	return 0;
}

CN_CBOR_EXPORT
cn_cbor *cn_cbor_decode(const unsigned char *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp)
{
	cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL};
	struct parse_buf pb;
	cn_cbor *ret = NULL;

	pb.buf = (unsigned char *)buf;
	pb.ebuf = (unsigned char *)buf + len;
	pb.err = CN_CBOR_NO_ERROR;
	ret = decode_item(&pb CBOR_CONTEXT_PARAM, &catcher);
	if (ret != NULL) {
		/* mark as top node */
		ret->parent = NULL;
	}
	else {
		if (catcher.first_child) {
			catcher.first_child->parent = 0;
			cn_cbor_free(catcher.first_child CBOR_CONTEXT_PARAM);
		}
		// fail:
		if (errp) {
			errp->err = pb.err;
			errp->pos = pb.buf - (unsigned char *)buf;
		}
		return NULL;
	}
	return ret;
}

#ifdef __cplusplus
}
#endif
