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

#include "honeysuckle.h"
#include "md4c-html.h"
#include "bindings.h"

struct concat_buffer {
   char *buf;
   size_t size;
   int index;
   bool ok;
};

static void md_callback(const MD_CHAR *html, MD_SIZE size, void *data)
{
   struct concat_buffer *d = data;

   if (!d->ok)
      return;

   if (d->index + size >= d->size) {
      char *new_buf = realloc(d->buf, d->size * 2);
      if (new_buf == NULL) {
	 // failed to allocate memory, abort!
	 d->ok = false;
	 return;
      }

      d->buf = new_buf;
      d->size *= 2;
   }
      
   memcpy((d->buf) + d->index, html, size);
   d->index += size;
}

int markdown(lua_State *L)
{
   char *markdown_buffer;
   hs_parse_args(L, hs_str(markdown_buffer));
   size_t len = strlen(markdown_buffer);

   unsigned int md_flags = MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_UNDERLINE;

   struct concat_buffer data;
   data.buf = malloc(128 * sizeof(char));
   data.size = 128 * sizeof(char);
   data.index = 0;
   data.ok = true;

   // fill out the buffer
   int error = md_html(markdown_buffer, len, md_callback, &data, md_flags, 0);
   if (error)
      hs_throw_error(L, "markdown parsing failed!");

   if (data.ok == false)
      hs_throw_error(L, "encountered error (re)allocating html buffer memory!");

   data.buf[data.index] = 0;

   lua_pushstring(L, data.buf);
   
   free(data.buf);

   return 1;
}