/* SDPX-License-Identifier: MIT */

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

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

#define CBOR_NO_FLOAT 1

#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
