#ifndef CN_CREATE_C
#define CN_CREATE_C

#ifdef __cplusplus
extern "C" {
#endif

#include <string.h>
#include <stdlib.h>

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

#define INIT_CB(v)                                 \
	if (errp) {                                    \
		errp->err = CN_CBOR_NO_ERROR;              \
	}                                              \
	(v) = CN_CALLOC_CONTEXT();                     \
	if (!(v)) {                                    \
		if (errp) {                                \
			errp->err = CN_CBOR_ERR_OUT_OF_MEMORY; \
		}                                          \
		return NULL;                               \
	}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_simple_create(int simpleValue, CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	if (24 <= simpleValue && simpleValue <= 31) {
		if (errp != NULL) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return NULL;
	}

	cn_cbor* ret;
	INIT_CB(ret);

	switch (simpleValue) {
		case 20:
			ret->type = CN_CBOR_FALSE;
			break;

		case 21:
			ret->type = CN_CBOR_TRUE;
			break;

		case 22:
			ret->type = CN_CBOR_NULL;
			break;

		default:
			ret->type = CN_CBOR_SIMPLE;
			ret->v.uint = simpleValue;
			break;
	}
	return ret;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_tag_create(int tag, cn_cbor* child, CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	ret->type = CN_CBOR_TAG;
	ret->v.sint = tag;
	ret->first_child = child;
	child->parent = ret;

	return ret;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	ret->type = CN_CBOR_MAP;
	ret->flags |= CN_CBOR_FL_COUNT;

	return ret;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len, CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	return cn_cbor_data_create2(data, len, CN_CBOR_FL_EXT_DATA CBOR_CONTEXT_PARAM, errp);
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_data_create2(const uint8_t* data, int len, int flags CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* ret = NULL;
	INIT_CB(ret);

	ret->type = CN_CBOR_BYTES;
	ret->length = len;
	ret->v.str = (const char*)data;	 // TODO: add v.ustr to the union?
	ret->flags |= flags;
	return ret;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_string_create(const char* data, CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	return cn_cbor_string_create2(data, CN_CBOR_FL_EXT_DATA CBOR_CONTEXT_PARAM, errp);
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_string_create2(const char* data, int flags CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* ret = NULL;
	INIT_CB(ret);

	ret->type = CN_CBOR_TEXT;
	ret->length = strlen(data);
	ret->v.str = data;
	ret->flags |= flags;

	return ret;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	if (value < 0) {
		ret->type = CN_CBOR_INT;
		ret->v.sint = value;
	}
	else {
		ret->type = CN_CBOR_UINT;
		ret->v.uint = value;
	}

	return ret;
}

#ifndef CBOR_NO_FLOAT
cn_cbor* cn_cbor_float_create(float value CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	ret->type = CN_CBOR_FLOAT;
	ret->v.f = value;

	return ret;
}

cn_cbor* cn_cbor_double_create(double value CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	ret->type = CN_CBOR_DOUBLE;
	ret->v.dbl = value;

	return ret;
}
#endif /* CBOR_NO_FLOAT */

static bool _append_kv(cn_cbor* cb_map, cn_cbor* key, cn_cbor* val)
{
	// Connect key and value and insert them into the map.
	key->parent = cb_map;
	key->next = val;
	val->parent = cb_map;
	val->next = NULL;

	if (cb_map->last_child) {
		cb_map->last_child->next = key;
	}
	else {
		cb_map->first_child = key;
	}
	cb_map->last_child = val;
	cb_map->length += 2;
	return true;
}

CN_CBOR_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map, cn_cbor* cb_key, cn_cbor* cb_value, cn_cbor_errback* errp)
{
	// Make sure input is a map. Otherwise
	if (!cb_map || !cb_key || !cb_value || cb_map->type != CN_CBOR_MAP) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	return _append_kv(cb_map, cb_key, cb_value);
}

CN_CBOR_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map, int64_t key, cn_cbor* cb_value CBOR_CONTEXT, cn_cbor_errback* errp)
{
	cn_cbor* cb_key;

	// Make sure input is a map. Otherwise
	if (!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp);
	if (!cb_key) {
		return false;
	}
	return _append_kv(cb_map, cb_key, cb_value);
}

CN_CBOR_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map, const char* key, cn_cbor* cb_value CBOR_CONTEXT, cn_cbor_errback* errp)
{
	return cn_cbor_mapput_string2(cb_map, key, cb_value, CN_CBOR_FL_EXT_DATA CBOR_CONTEXT_PARAM, errp);
}

CN_CBOR_EXPORT
bool cn_cbor_mapput_string2(cn_cbor* cb_map,
	const char* key,
	cn_cbor* cb_value,
	int flags CBOR_CONTEXT,
	cn_cbor_errback* errp)
{
	// Make sure input is a map. Otherwise
	if (!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	cn_cbor* cb_key = cn_cbor_string_create2(key, flags CBOR_CONTEXT_PARAM, errp);
	if (!cb_key) {
		return false;
	}
	return _append_kv(cb_map, cb_key, cb_value);
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	ret->type = CN_CBOR_ARRAY;
	ret->flags |= CN_CBOR_FL_COUNT;

	return ret;
}

CN_CBOR_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array, cn_cbor* cb_value, cn_cbor_errback* errp)
{
	// Make sure input is an array.
	if (!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	cb_value->parent = cb_array;
	cb_value->next = NULL;
	if (cb_array->last_child) {
		cb_array->last_child->next = cb_value;
	}
	else {
		cb_array->first_child = cb_value;
	}
	cb_array->last_child = cb_value;
	cb_array->length++;
	return true;
}

CN_CBOR_EXPORT
cn_cbor* cn_cbor_chunked_create(int type, CBOR_CONTEXT_COMMA cn_cbor_errback* errp)
{
	cn_cbor* ret;
	INIT_CB(ret);

	switch (type) {
		case CN_CBOR_BYTES:
			ret->type = CN_CBOR_BYTES_CHUNKED;
			break;

		case CN_CBOR_TEXT:
			ret->type = CN_CBOR_TEXT_CHUNKED;
			break;

		default:
			return NULL;
	}

	ret->flags |= CN_CBOR_FL_INDEF;

	return ret;
}

CN_CBOR_EXPORT
bool cn_cbor_chunked_append(cn_cbor* cb_array, cn_cbor* cb_value, cn_cbor_errback* errp)
{
	// Make sure input is an array.
	if (!cb_array || !cb_value || (cb_array->type != CN_CBOR_BYTES_CHUNKED && cb_array->type != CN_CBOR_TEXT_CHUNKED)) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	if (cb_array->type == CN_CBOR_BYTES_CHUNKED && cb_value->type != CN_CBOR_BYTES) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	if (cb_array->type == CN_CBOR_TEXT_CHUNKED && cb_value->type != CN_CBOR_TEXT) {
		if (errp) {
			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	cb_value->parent = cb_array;
	cb_value->next = NULL;
	if (cb_array->last_child) {
		cb_array->last_child->next = cb_value;
	}
	else {
		cb_array->first_child = cb_value;
	}
	cb_array->last_child = cb_value;
	cb_array->length++;
	return true;
}

#ifdef __cplusplus
}
#endif

#endif /* CN_CBOR_C */
