#ifndef CN_PRINT_C
#define CN_PRINT_C
#define CN_INCLUDE_DUMPER
#ifdef CN_INCLUDE_DUMPER
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdio.h>

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

#include <stdio.h>
#ifdef MSV_CRT
#include <winsock2.h>
#else
#define _snprintf snprintf
#endif
#include <string.h>
#include <stdbool.h>
#include <assert.h>

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

typedef struct _write_state {
	char *rgbOutput;
	ssize_t ib;
	size_t cbLeft;
	uint8_t *rgFlags;
	const char *szIndentWith;
	const char *szEndOfLine;
} cn_write_state;

typedef void (*cn_visit_func)(const cn_cbor *cb, int depth, void *context);
extern void _visit(const cn_cbor *cb, cn_visit_func visitor, cn_visit_func breaker, void *context);

const char RgchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

bool _isWritable(cn_write_state *ws, size_t cb)
{
	if (ws->rgbOutput == NULL)
		return true;
	if ((ws->ib < 0) || (ws->ib + cb > ws->cbLeft)) {
		ws->ib = -1;
		return false;
	}
	return true;
}

void write_data(cn_write_state *ws, const char *sz, size_t cb)
{
	if (_isWritable(ws, cb)) {
		if (ws->rgbOutput != NULL)
			memcpy(ws->rgbOutput + ws->ib, sz, cb);
		ws->ib += cb;
	}
}

void _doIndent(cn_write_state *ws, int depth)
{
	int i;
	char *sz = ws->rgbOutput + ws->ib;
	size_t cbIndentWith = strlen(ws->szIndentWith);
	int cbIndent = depth * cbIndentWith;

	if (ws->rgbOutput == NULL) {
		ws->ib += cbIndent;
		return;
	}

	if (_isWritable(ws, cbIndent)) {
		for (i = 0; i < depth; i++) {
			memcpy(sz, ws->szIndentWith, cbIndentWith);
			sz += cbIndentWith;
		}
	}

	ws->ib += cbIndent;

	return;
}

void _print_encoder(const cn_cbor *cb, int depth, void *context)
{
	int i;
	char rgchT[256];
	int cch;
	cn_write_state *ws = (cn_write_state *)context;
	uint8_t flags = ws->rgFlags[depth];

	if (flags & 1) {
		write_data(ws, ", ", 2);
		ws->rgFlags[depth] &= 0xfe;

		if (ws->szIndentWith) {
			write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
			_doIndent(ws, depth);
		}
	}

	if (flags & 2) {
		write_data(ws, ": ", 2);
		ws->rgFlags[depth] &= 0xfd;
	}

	switch (cb->type) {
		case CN_CBOR_BYTES_CHUNKED:
		case CN_CBOR_TEXT_CHUNKED:
			break;

		case CN_CBOR_ARRAY:
			write_data(ws, "[", 1);
			ws->rgFlags[depth] |= 4;

			if (ws->szIndentWith) {
				write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
				_doIndent(ws, depth + 1);
			}
			break;

		case CN_CBOR_MAP:
			write_data(ws, "{", 1);
			ws->rgFlags[depth] |= 8;

			if (ws->szIndentWith) {
				write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
				_doIndent(ws, depth + 1);
			}
			break;

		case CN_CBOR_TAG:
		case CN_CBOR_UINT:
		case CN_CBOR_SIMPLE:
			cch = _snprintf(rgchT, sizeof(rgchT), "%u", (unsigned int)cb->v.uint);
			write_data(ws, rgchT, cch);
			break;

		case CN_CBOR_FALSE:
			write_data(ws, "false", 5);
			break;

		case CN_CBOR_TRUE:
			write_data(ws, "true", 4);
			break;

		case CN_CBOR_NULL:
			write_data(ws, "null", 4);
			break;

		case CN_CBOR_UNDEF:
			write_data(ws, "undef", 5);
			break;

		case CN_CBOR_INT:
			cch = _snprintf(rgchT, sizeof(rgchT), "%d", (unsigned int)cb->v.sint);
			write_data(ws, rgchT, cch);
			break;

#ifndef CBOR_NO_FLOAT
		case CN_CBOR_FLOAT:
			cch = _snprintf(rgchT, sizeof(rgchT), "%f", cb->v.f);
			write_data(ws, rgchT, cch);
			break;

		case CN_CBOR_DOUBLE:
			cch = _snprintf(rgchT, sizeof(rgchT), "%f", cb->v.dbl);
			write_data(ws, rgchT, cch);
			break;
#endif

		case CN_CBOR_INVALID:
			write_data(ws, "invalid", 7);
			break;

		case CN_CBOR_TEXT:
			write_data(ws, "\"", 1);
			write_data(ws, cb->v.str, cb->length);
			write_data(ws, "\"", 1);
			break;

		case CN_CBOR_BYTES:
			write_data(ws, "h'", 2);
			for (i = 0; i < cb->length; i++) {
				write_data(ws, &RgchHex[(cb->v.str[i] / 16) & 0xf], 1);
				write_data(ws, &RgchHex[cb->v.str[i] & 0xf], 1);
			}
			write_data(ws, "\'", 1);
			break;
	}

	if (depth > 0) {
		if (ws->rgFlags[depth - 1] & 4)
			ws->rgFlags[depth] |= 1;
		else if (ws->rgFlags[depth - 1] & 8) {
			if (flags & 2)
				ws->rgFlags[depth] |= 1;
			else
				ws->rgFlags[depth] |= 2;
		}
	}
}

void _print_breaker(const cn_cbor *cb, int depth, void *context)
{
	cn_write_state *ws = (cn_write_state *)context;

	switch (cb->type) {
		case CN_CBOR_ARRAY:
			if (ws->szIndentWith) {
				write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
				_doIndent(ws, depth);
			}

			write_data(ws, "]", 1);
			ws->rgFlags[depth + 1] = 0;
			break;

		case CN_CBOR_MAP:
			if (ws->szIndentWith) {
				write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
				_doIndent(ws, depth);
			}

			write_data(ws, "}", 1);
			ws->rgFlags[depth + 1] = 0;
			break;

		default:
			break;
	}
}

ssize_t cn_cbor_printer_write(char *rgbBuffer,
	size_t cbBuffer,
	const cn_cbor *cb,
	const char *szIndentWith,
	const char *szEndOfLine)
{
	uint8_t flags[128] = {0};
	char rgchZero[1] = {0};

	cn_write_state ws = {rgbBuffer, 0, cbBuffer, flags, szIndentWith, szEndOfLine};
	_visit(cb, _print_encoder, _print_breaker, &ws);
	write_data(&ws, rgchZero, 1);

	return ws.ib;
}

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

#endif	// CN_INCLUDE_DUMPER
#endif	// CN_PRINT_C
