#include <stdlib.h>
#include "buffer.h"
#include "chunk.h"
#include "cmark.h"
#include "utf8.h"
#include "render.h"

static inline
void S_cr(cmark_renderer *renderer)
{
	if (renderer->need_cr < 1) {
		renderer->need_cr = 1;
	}
}

static inline
void S_blankline(cmark_renderer *renderer)
{
	if (renderer->need_cr < 2) {
		renderer->need_cr = 2;
	}
}

static
void S_out(cmark_renderer *renderer,
	   const char *source,
	   bool wrap,
	   cmark_escaping escape)
{
	int length = cmark_strbuf_safe_strlen(source);
	unsigned char nextc;
	int32_t c;
	int i = 0;
	int len;
	cmark_chunk remainder = cmark_chunk_literal("");
	int k = renderer->buffer->size - 1;

	wrap = wrap && !renderer->no_wrap;

	if (renderer->in_tight_list_item && renderer->need_cr > 1) {
		renderer->need_cr = 1;
	}
	while (renderer->need_cr) {
		if (k < 0 || renderer->buffer->ptr[k] == '\n') {
			k -= 1;
		} else {
			cmark_strbuf_putc(renderer->buffer, '\n');
			if (renderer->need_cr > 1) {
				cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
				                 renderer->prefix->size);
			}
		}
		renderer->column = 0;
		renderer->begin_line = true;
		renderer->need_cr -= 1;
	}

	while (i < length) {
		if (renderer->begin_line) {
			cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
			                 renderer->prefix->size);
			// note: this assumes prefix is ascii:
			renderer->column = renderer->prefix->size;
		}

		len = utf8proc_iterate((const uint8_t *)source + i, length - i, &c);
		if (len == -1) { // error condition
			return;  // return without rendering rest of string
		}
		nextc = source[i + len];
		if (c == 32 && wrap) {
			if (!renderer->begin_line) {
				cmark_strbuf_putc(renderer->buffer, ' ');
				renderer->column += 1;
				renderer->begin_line = false;
				renderer->last_breakable = renderer->buffer->size -
				                        1;
				// skip following spaces
				while (source[i + 1] == ' ') {
					i++;
				}
			}

		} else if (c == 10) {
			cmark_strbuf_putc(renderer->buffer, '\n');
			renderer->column = 0;
			renderer->begin_line = true;
			renderer->last_breakable = 0;
		} else {
			(renderer->outc)(renderer, escape, c, nextc);
		}

		// If adding the character went beyond width, look for an
		// earlier place where the line could be broken:
		if (renderer->width > 0 &&
		    renderer->column > renderer->width &&
		    !renderer->begin_line &&
		    renderer->last_breakable > 0) {

			// copy from last_breakable to remainder
			cmark_chunk_set_cstr(&remainder, (char *) renderer->buffer->ptr + renderer->last_breakable + 1);
			// truncate at last_breakable
			cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);
			// add newline, prefix, and remainder
			cmark_strbuf_putc(renderer->buffer, '\n');
			cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
			                 renderer->prefix->size);
			cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);
			renderer->column = renderer->prefix->size + remainder.len;
			cmark_chunk_free(&remainder);
			renderer->last_breakable = 0;
			renderer->begin_line = false;
		}

		i += len;
	}
}

// Assumes no newlines, assumes ascii content:
void
cmark_render_ascii(cmark_renderer* renderer, const char* s)
{
	int origsize = renderer->buffer->size;
	cmark_strbuf_puts(renderer->buffer, s);
	renderer->column += renderer->buffer->size - origsize;
}

void
cmark_render_code_point(cmark_renderer *renderer, uint8_t c)
{
	utf8proc_encode_char(c, renderer->buffer);
	renderer->column += 1;
}

char*
cmark_render(cmark_node *root,
	     int options,
	     int width,
	     void (*outc)(cmark_renderer*,
			  cmark_escaping,
			  int32_t,
			  unsigned char),
	     int (*render_node)(cmark_renderer *renderer,
				cmark_node *node,
				cmark_event_type ev_type,
				int options))
{
	cmark_strbuf pref = GH_BUF_INIT;
	cmark_strbuf buf = GH_BUF_INIT;
	cmark_node *cur;
	cmark_event_type ev_type;
	char *result;
	cmark_iter *iter = cmark_iter_new(root);

	cmark_renderer renderer = { &buf, &pref, 0, width,
				    0, 0, true, false, false,
	                            outc, S_cr, S_blankline, S_out };

	while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
		cur = cmark_iter_get_node(iter);
		if (!render_node(&renderer, cur, ev_type, options)) {
			// a false value causes us to skip processing
			// the node's contents.  this is used for
			// autolinks.
			cmark_iter_reset(iter, cur, CMARK_EVENT_EXIT);
		}
	}

	// ensure final newline
	if (renderer.buffer->ptr[renderer.buffer->size - 1] != '\n') {
		cmark_strbuf_putc(renderer.buffer, '\n');
	}

	result = (char *)cmark_strbuf_detach(renderer.buffer);

	cmark_iter_free(iter);
	cmark_strbuf_free(renderer.prefix);
	cmark_strbuf_free(renderer.buffer);

	return result;
}
