#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
