#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

#include "cmark_ctype.h"
#include "config.h"
#include "parser.h"
#include "cmark.h"
#include "node.h"
#include "references.h"
#include "utf8.h"
#include "scanners.h"
#include "inlines.h"
#include "houdini.h"
#include "buffer.h"

#define CODE_INDENT 4
#define TAB_STOP 4

#define peek_at(i, n) (i)->data[n]

static inline bool S_is_line_end_char(char c) {
  return (c == '\n' || c == '\r');
}

static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
                          size_t len, bool eof);

static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
                           bufsize_t bytes);

static cmark_node *make_block(cmark_node_type tag, int start_line,
                              int start_column) {
  cmark_node *e;

  e = (cmark_node *)calloc(1, sizeof(*e));
  if (e != NULL) {
    e->type = tag;
    e->open = true;
    e->start_line = start_line;
    e->start_column = start_column;
    e->end_line = start_line;
    cmark_strbuf_init(&e->string_content, 32);
  }

  return e;
}

// Create a root document node.
static cmark_node *make_document() {
  cmark_node *e = make_block(NODE_DOCUMENT, 1, 1);
  return e;
}

cmark_parser *cmark_parser_new(int options) {
  cmark_parser *parser = (cmark_parser *)malloc(sizeof(cmark_parser));
  cmark_node *document = make_document();
  cmark_strbuf *line = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
  cmark_strbuf *buf = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
  cmark_strbuf_init(line, 256);
  cmark_strbuf_init(buf, 0);

  parser->refmap = cmark_reference_map_new();
  parser->root = document;
  parser->current = document;
  parser->line_number = 0;
  parser->offset = 0;
  parser->column = 0;
  parser->first_nonspace = 0;
  parser->first_nonspace_column = 0;
  parser->indent = 0;
  parser->blank = false;
  parser->curline = line;
  parser->last_line_length = 0;
  parser->linebuf = buf;
  parser->options = options;

  return parser;
}

void cmark_parser_free(cmark_parser *parser) {
  cmark_strbuf_free(parser->curline);
  free(parser->curline);
  cmark_strbuf_free(parser->linebuf);
  free(parser->linebuf);
  cmark_reference_map_free(parser->refmap);
  free(parser);
}

static cmark_node *finalize(cmark_parser *parser, cmark_node *b);

// Returns true if line has only space characters, else false.
static bool is_blank(cmark_strbuf *s, bufsize_t offset) {
  while (offset < s->size) {
    switch (s->ptr[offset]) {
    case '\r':
    case '\n':
      return true;
    case ' ':
      offset++;
      break;
    case '\t':
      offset++;
      break;
    default:
      return false;
    }
  }

  return true;
}

static inline bool can_contain(cmark_node_type parent_type,
                               cmark_node_type child_type) {
  return (parent_type == NODE_DOCUMENT || parent_type == NODE_BLOCK_QUOTE ||
          parent_type == NODE_ITEM ||
          (parent_type == NODE_LIST && child_type == NODE_ITEM));
}

static inline bool accepts_lines(cmark_node_type block_type) {
  return (block_type == NODE_PARAGRAPH || block_type == NODE_HEADER ||
          block_type == NODE_CODE_BLOCK);
}

static void add_line(cmark_node *node, cmark_chunk *ch, bufsize_t offset) {
  assert(node->open);
  cmark_strbuf_put(&node->string_content, ch->data + offset, ch->len - offset);
}

static void remove_trailing_blank_lines(cmark_strbuf *ln) {
  bufsize_t i;
  unsigned char c;

  for (i = ln->size - 1; i >= 0; --i) {
    c = ln->ptr[i];

    if (c != ' ' && c != '\t' && !S_is_line_end_char(c))
      break;
  }

  if (i < 0) {
    cmark_strbuf_clear(ln);
    return;
  }

  for (; i < ln->size; ++i) {
    c = ln->ptr[i];

    if (!S_is_line_end_char(c))
      continue;

    cmark_strbuf_truncate(ln, i);
    break;
  }
}

// Check to see if a node ends with a blank line, descending
// if needed into lists and sublists.
static bool ends_with_blank_line(cmark_node *node) {
  cmark_node *cur = node;
  while (cur != NULL) {
    if (cur->last_line_blank) {
      return true;
    }
    if (cur->type == NODE_LIST || cur->type == NODE_ITEM) {
      cur = cur->last_child;
    } else {
      cur = NULL;
    }
  }
  return false;
}

// Break out of all containing lists
static int break_out_of_lists(cmark_parser *parser, cmark_node **bptr) {
  cmark_node *container = *bptr;
  cmark_node *b = parser->root;
  // find first containing NODE_LIST:
  while (b && b->type != NODE_LIST) {
    b = b->last_child;
  }
  if (b) {
    while (container && container != b) {
      container = finalize(parser, container);
    }
    finalize(parser, b);
    *bptr = b->parent;
  }
  return 0;
}

static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
  bufsize_t pos;
  cmark_node *item;
  cmark_node *subitem;
  cmark_node *parent;

  parent = b->parent;

  assert(b->open); // shouldn't call finalize on closed blocks
  b->open = false;

  if (parser->curline->size == 0) {
    // end of input - line number has not been incremented
    b->end_line = parser->line_number;
    b->end_column = parser->last_line_length;
  } else if (b->type == NODE_DOCUMENT ||
             (b->type == NODE_CODE_BLOCK && b->as.code.fenced) ||
             (b->type == NODE_HEADER && b->as.header.setext)) {
    b->end_line = parser->line_number;
    b->end_column = parser->curline->size;
    if (b->end_column && parser->curline->ptr[b->end_column - 1] == '\n')
      b->end_column -= 1;
    if (b->end_column && parser->curline->ptr[b->end_column - 1] == '\r')
      b->end_column -= 1;
  } else {
    b->end_line = parser->line_number - 1;
    b->end_column = parser->last_line_length;
  }

  switch (b->type) {
  case NODE_PARAGRAPH:
    while (cmark_strbuf_at(&b->string_content, 0) == '[' &&
           (pos = cmark_parse_reference_inline(&b->string_content,
                                               parser->refmap))) {

      cmark_strbuf_drop(&b->string_content, pos);
    }
    if (is_blank(&b->string_content, 0)) {
      // remove blank node (former reference def)
      cmark_node_free(b);
    }
    break;

  case NODE_CODE_BLOCK:
    if (!b->as.code.fenced) { // indented code
      remove_trailing_blank_lines(&b->string_content);
      cmark_strbuf_putc(&b->string_content, '\n');
    } else {

      // first line of contents becomes info
      for (pos = 0; pos < b->string_content.size; ++pos) {
        if (S_is_line_end_char(b->string_content.ptr[pos]))
          break;
      }
      assert(pos < b->string_content.size);

      cmark_strbuf tmp = GH_BUF_INIT;
      houdini_unescape_html_f(&tmp, b->string_content.ptr, pos);
      cmark_strbuf_trim(&tmp);
      cmark_strbuf_unescape(&tmp);
      b->as.code.info = cmark_chunk_buf_detach(&tmp);

      if (b->string_content.ptr[pos] == '\r')
        pos += 1;
      if (b->string_content.ptr[pos] == '\n')
        pos += 1;
      cmark_strbuf_drop(&b->string_content, pos);
    }
    b->as.code.literal = cmark_chunk_buf_detach(&b->string_content);
    break;

  case NODE_HTML:
    b->as.literal = cmark_chunk_buf_detach(&b->string_content);
    break;

  case NODE_LIST:            // determine tight/loose status
    b->as.list.tight = true; // tight by default
    item = b->first_child;

    while (item) {
      // check for non-final non-empty list item ending with blank line:
      if (item->last_line_blank && item->next) {
        b->as.list.tight = false;
        break;
      }
      // recurse into children of list item, to see if there are
      // spaces between them:
      subitem = item->first_child;
      while (subitem) {
        if (ends_with_blank_line(subitem) && (item->next || subitem->next)) {
          b->as.list.tight = false;
          break;
        }
        subitem = subitem->next;
      }
      if (!(b->as.list.tight)) {
        break;
      }
      item = item->next;
    }

    break;

  default:
    break;
  }
  return parent;
}

// Add a node as child of another.  Return pointer to child.
static cmark_node *add_child(cmark_parser *parser, cmark_node *parent,
                             cmark_node_type block_type, int start_column) {
  assert(parent);

  // if 'parent' isn't the kind of node that can accept this child,
  // then back up til we hit a node that can.
  while (!can_contain(parent->type, block_type)) {
    parent = finalize(parser, parent);
  }

  cmark_node *child = make_block(block_type, parser->line_number, start_column);
  child->parent = parent;

  if (parent->last_child) {
    parent->last_child->next = child;
    child->prev = parent->last_child;
  } else {
    parent->first_child = child;
    child->prev = NULL;
  }
  parent->last_child = child;
  return child;
}

// Walk through node and all children, recursively, parsing
// string content into inline content where appropriate.
static void process_inlines(cmark_node *root, cmark_reference_map *refmap,
                            int options) {
  cmark_iter *iter = cmark_iter_new(root);
  cmark_node *cur;
  cmark_event_type ev_type;

  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
    cur = cmark_iter_get_node(iter);
    if (ev_type == CMARK_EVENT_ENTER) {
      if (cur->type == NODE_PARAGRAPH || cur->type == NODE_HEADER) {
        cmark_parse_inlines(cur, refmap, options);
      }
    }
  }

  cmark_iter_free(iter);
}

// Attempts to parse a list item marker (bullet or enumerated).
// On success, returns length of the marker, and populates
// data with the details.  On failure, returns 0.
static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos,
                                   cmark_list **dataptr) {
  unsigned char c;
  bufsize_t startpos;
  cmark_list *data;

  startpos = pos;
  c = peek_at(input, pos);

  if (c == '*' || c == '-' || c == '+') {
    pos++;
    if (!cmark_isspace(peek_at(input, pos))) {
      return 0;
    }
    data = (cmark_list *)calloc(1, sizeof(*data));
    if (data == NULL) {
      return 0;
    } else {
      data->marker_offset = 0; // will be adjusted later
      data->list_type = CMARK_BULLET_LIST;
      data->bullet_char = c;
      data->start = 1;
      data->delimiter = CMARK_PERIOD_DELIM;
      data->tight = false;
    }
  } else if (cmark_isdigit(c)) {
    int start = 0;
    int digits = 0;

    do {
      start = (10 * start) + (peek_at(input, pos) - '0');
      pos++;
      digits++;
      // We limit to 9 digits to avoid overflow,
      // assuming max int is 2^31 - 1
      // This also seems to be the limit for 'start' in some browsers.
    } while (digits < 9 && cmark_isdigit(peek_at(input, pos)));

    c = peek_at(input, pos);
    if (c == '.' || c == ')') {
      pos++;
      if (!cmark_isspace(peek_at(input, pos))) {
        return 0;
      }
      data = (cmark_list *)calloc(1, sizeof(*data));
      if (data == NULL) {
        return 0;
      } else {
        data->marker_offset = 0; // will be adjusted later
        data->list_type = CMARK_ORDERED_LIST;
        data->bullet_char = 0;
        data->start = start;
        data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM);
        data->tight = false;
      }
    } else {
      return 0;
    }

  } else {
    return 0;
  }

  *dataptr = data;
  return (pos - startpos);
}

// Return 1 if list item belongs in list, else 0.
static int lists_match(cmark_list *list_data, cmark_list *item_data) {
  return (list_data->list_type == item_data->list_type &&
          list_data->delimiter == item_data->delimiter &&
          // list_data->marker_offset == item_data.marker_offset &&
          list_data->bullet_char == item_data->bullet_char);
}

static cmark_node *finalize_document(cmark_parser *parser) {
  while (parser->current != parser->root) {
    parser->current = finalize(parser, parser->current);
  }

  finalize(parser, parser->root);
  process_inlines(parser->root, parser->refmap, parser->options);

  return parser->root;
}

cmark_node *cmark_parse_file(FILE *f, int options) {
  unsigned char buffer[4096];
  cmark_parser *parser = cmark_parser_new(options);
  size_t bytes;
  cmark_node *document;

  while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) {
    bool eof = bytes < sizeof(buffer);
    S_parser_feed(parser, buffer, bytes, eof);
    if (eof) {
      break;
    }
  }

  document = cmark_parser_finish(parser);
  cmark_parser_free(parser);
  return document;
}

cmark_node *cmark_parse_document(const char *buffer, size_t len, int options) {
  cmark_parser *parser = cmark_parser_new(options);
  cmark_node *document;

  S_parser_feed(parser, (const unsigned char *)buffer, len, true);

  document = cmark_parser_finish(parser);
  cmark_parser_free(parser);
  return document;
}

void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {
  S_parser_feed(parser, (const unsigned char *)buffer, len, false);
}

static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
                          size_t len, bool eof) {
  const unsigned char *end = buffer + len;
  static const uint8_t repl[] = {239, 191, 189};

  while (buffer < end) {
    const unsigned char *eol;
    bufsize_t chunk_len;
    bool process = false;
    for (eol = buffer; eol < end; ++eol) {
      if (S_is_line_end_char(*eol)) {
        if (eol < end && *eol == '\r')
          eol++;
        if (eol < end && *eol == '\n')
          eol++;
        process = true;
        break;
      }
      if (*eol == '\0' && eol < end) {
        break;
      }
    }
    if (eol >= end && eof) {
      process = true;
    }

    chunk_len = cmark_strbuf_check_bufsize(eol - buffer);
    if (process) {
      if (parser->linebuf->size > 0) {
        cmark_strbuf_put(parser->linebuf, buffer, chunk_len);
        S_process_line(parser, parser->linebuf->ptr, parser->linebuf->size);
        cmark_strbuf_clear(parser->linebuf);
      } else {
        S_process_line(parser, buffer, chunk_len);
      }
    } else {
      if (eol < end && *eol == '\0') {
        // omit NULL byte
        cmark_strbuf_put(parser->linebuf, buffer, chunk_len);
        // add replacement character
        cmark_strbuf_put(parser->linebuf, repl, 3);
        chunk_len += 1; // so we advance the buffer past NULL
      } else {
        cmark_strbuf_put(parser->linebuf, buffer, chunk_len);
      }
    }

    buffer += chunk_len;
  }
}

static void chop_trailing_hashtags(cmark_chunk *ch) {
  bufsize_t n, orig_n;

  cmark_chunk_rtrim(ch);
  orig_n = n = ch->len - 1;

  // if string ends in space followed by #s, remove these:
  while (n >= 0 && peek_at(ch, n) == '#')
    n--;

  // Check for a space before the final #s:
  if (n != orig_n && n >= 0 &&
      (peek_at(ch, n) == ' ' || peek_at(ch, n) == '\t')) {
    ch->len = n;
    cmark_chunk_rtrim(ch);
  }
}

static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
  char c;
  int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);

  parser->first_nonspace = parser->offset;
  parser->first_nonspace_column = parser->column;
  while ((c = peek_at(input, parser->first_nonspace))) {
    if (c == ' ') {
      parser->first_nonspace += 1;
      parser->first_nonspace_column += 1;
      chars_to_tab = chars_to_tab - 1;
      if (chars_to_tab == 0) {
        chars_to_tab = TAB_STOP;
      }
    } else if (c == '\t') {
      parser->first_nonspace += 1;
      parser->first_nonspace_column += chars_to_tab;
      chars_to_tab = TAB_STOP;
    } else {
      break;
    }
  }

  parser->indent = parser->first_nonspace_column - parser->column;
  parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));
}

static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
                             bufsize_t count, bool columns) {
  char c;
  int chars_to_tab;
  while (count > 0 && (c = peek_at(input, parser->offset))) {
    if (c == '\t') {
      chars_to_tab = 4 - (parser->column % TAB_STOP);
      parser->column += chars_to_tab;
      parser->offset += 1;
      count -= (columns ? chars_to_tab : 1);
    } else {
      parser->offset += 1;
      parser->column += 1; // assume ascii; block starts are ascii
      count -= 1;
    }
  }
}

static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
                           bufsize_t bytes) {
  cmark_node *last_matched_container;
  bufsize_t matched = 0;
  int lev = 0;
  int i;
  cmark_list *data = NULL;
  bool all_matched = true;
  cmark_node *container;
  bool indented;
  cmark_chunk input;
  bool maybe_lazy;

  if (parser->options & CMARK_OPT_VALIDATE_UTF8) {
    cmark_utf8proc_check(parser->curline, buffer, bytes);
  } else {
    cmark_strbuf_put(parser->curline, buffer, bytes);
  }
  parser->offset = 0;
  parser->column = 0;
  parser->blank = false;

  input.data = parser->curline->ptr;
  input.len = parser->curline->size;

  // container starts at the document root.
  container = parser->root;

  parser->line_number++;

  // for each containing node, try to parse the associated line start.
  // bail out on failure:  container will point to the last matching node.

  while (container->last_child && container->last_child->open) {
    container = container->last_child;

    S_find_first_nonspace(parser, &input);

    if (container->type == NODE_BLOCK_QUOTE) {
      matched =
          parser->indent <= 3 && peek_at(&input, parser->first_nonspace) == '>';
      if (matched) {
        S_advance_offset(parser, &input, parser->indent + 1, true);
        if (peek_at(&input, parser->offset) == ' ')
          parser->offset++;
      } else {
        all_matched = false;
      }

    } else if (container->type == NODE_ITEM) {
      if (parser->indent >=
          container->as.list.marker_offset + container->as.list.padding) {
        S_advance_offset(parser, &input, container->as.list.marker_offset +
                                             container->as.list.padding,
                         true);
      } else if (parser->blank && container->first_child != NULL) {
        // if container->first_child is NULL, then the opening line
        // of the list item was blank after the list marker; in this
        // case, we are done with the list item.
        S_advance_offset(parser, &input,
                         parser->first_nonspace - parser->offset, false);
      } else {
        all_matched = false;
      }

    } else if (container->type == NODE_CODE_BLOCK) {

      if (!container->as.code.fenced) { // indented
        if (parser->indent >= CODE_INDENT) {
          S_advance_offset(parser, &input, CODE_INDENT, true);
        } else if (parser->blank) {
          S_advance_offset(parser, &input,
                           parser->first_nonspace - parser->offset, false);
        } else {
          all_matched = false;
        }
      } else { // fenced
        matched = 0;
        if (parser->indent <= 3 && (peek_at(&input, parser->first_nonspace) ==
                                    container->as.code.fence_char)) {
          matched = scan_close_code_fence(&input, parser->first_nonspace);
        }
        if (matched >= container->as.code.fence_length) {
          // closing fence - and since we're at
          // the end of a line, we can return:
          all_matched = false;
          S_advance_offset(parser, &input, matched, false);
          parser->current = finalize(parser, container);
          goto finished;
        } else {
          // skip opt. spaces of fence parser->offset
          i = container->as.code.fence_offset;
          while (i > 0 && peek_at(&input, parser->offset) == ' ') {
            S_advance_offset(parser, &input, 1, false);
            i--;
          }
        }
      }
    } else if (container->type == NODE_HEADER) {

      // a header can never contain more than one line
      all_matched = false;

    } else if (container->type == NODE_HTML) {

      switch (container->as.html_block_type) {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
        // these types of blocks can accept blanks
        break;
      case 6:
      case 7:
        if (parser->blank) {
          all_matched = false;
        }
        break;
      default:
        fprintf(stderr, "Error (%s:%d): Unknown HTML block type %d\n", __FILE__,
                __LINE__, container->as.html_block_type);
        exit(1);
      }

    } else if (container->type == NODE_PARAGRAPH) {

      if (parser->blank) {
        all_matched = false;
      }
    }

    if (!all_matched) {
      container = container->parent; // back up to last matching node
      break;
    }
  }

  last_matched_container = container;

  // check to see if we've hit 2nd blank line, break out of list:
  if (parser->blank && container->last_line_blank) {
    break_out_of_lists(parser, &container);
  }

  maybe_lazy = parser->current->type == NODE_PARAGRAPH;
  // try new container starts:
  while (container->type != NODE_CODE_BLOCK && container->type != NODE_HTML) {

    S_find_first_nonspace(parser, &input);
    indented = parser->indent >= CODE_INDENT;

    if (!indented && peek_at(&input, parser->first_nonspace) == '>') {

      S_advance_offset(parser, &input,
                       parser->first_nonspace + 1 - parser->offset, false);
      // optional following character
      if (peek_at(&input, parser->offset) == ' ')
        S_advance_offset(parser, &input, 1, false);
      container =
          add_child(parser, container, NODE_BLOCK_QUOTE, parser->offset + 1);

    } else if (!indented && (matched = scan_atx_header_start(
                                 &input, parser->first_nonspace))) {

      S_advance_offset(parser, &input,
                       parser->first_nonspace + matched - parser->offset,
                       false);
      container = add_child(parser, container, NODE_HEADER, parser->offset + 1);

      bufsize_t hashpos =
          cmark_chunk_strchr(&input, '#', parser->first_nonspace);
      int level = 0;

      while (peek_at(&input, hashpos) == '#') {
        level++;
        hashpos++;
      }
      container->as.header.level = level;
      container->as.header.setext = false;

    } else if (!indented && (matched = scan_open_code_fence(
                                 &input, parser->first_nonspace))) {

      container = add_child(parser, container, NODE_CODE_BLOCK,
                            parser->first_nonspace + 1);
      container->as.code.fenced = true;
      container->as.code.fence_char = peek_at(&input, parser->first_nonspace);
      container->as.code.fence_length = matched;
      container->as.code.fence_offset = parser->first_nonspace - parser->offset;
      container->as.code.info = cmark_chunk_literal("");
      S_advance_offset(parser, &input,
                       parser->first_nonspace + matched - parser->offset,
                       false);

    } else if (!indented && ((matched = scan_html_block_start(
                                  &input, parser->first_nonspace)) ||
                             (container->type != NODE_PARAGRAPH &&
                              (matched = scan_html_block_start_7(
                                   &input, parser->first_nonspace))))) {

      container =
          add_child(parser, container, NODE_HTML, parser->first_nonspace + 1);
      container->as.html_block_type = matched;
      // note, we don't adjust parser->offset because the tag is part of the
      // text

    } else if (!indented && container->type == NODE_PARAGRAPH &&
               (lev =
                    scan_setext_header_line(&input, parser->first_nonspace)) &&
               // check that there is only one line in the paragraph:
               (cmark_strbuf_strrchr(
                    &container->string_content, '\n',
                    cmark_strbuf_len(&container->string_content) - 2) < 0)) {

      container->type = NODE_HEADER;
      container->as.header.level = lev;
      container->as.header.setext = true;
      S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);

    } else if (!indented &&
               !(container->type == NODE_PARAGRAPH && !all_matched) &&
               (matched = scan_hrule(&input, parser->first_nonspace))) {

      // it's only now that we know the line is not part of a setext header:
      container =
          add_child(parser, container, NODE_HRULE, parser->first_nonspace + 1);
      container = finalize(parser, container);
      S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);

    } else if ((matched =
                    parse_list_marker(&input, parser->first_nonspace, &data)) &&
               (!indented || container->type == NODE_LIST)) {
      // Note that we can have new list items starting with >= 4
      // spaces indent, as long as the list container is still open.

      // compute padding:
      S_advance_offset(parser, &input,
                       parser->first_nonspace + matched - parser->offset,
                       false);
      i = 0;
      while (i <= 5 && peek_at(&input, parser->offset + i) == ' ') {
        i++;
      }
      // i = number of spaces after marker, up to 5
      if (i >= 5 || i < 1 ||
          S_is_line_end_char(peek_at(&input, parser->offset))) {
        data->padding = matched + 1;
        if (i > 0) {
          S_advance_offset(parser, &input, 1, false);
        }
      } else {
        data->padding = matched + i;
        S_advance_offset(parser, &input, i, true);
      }

      // check container; if it's a list, see if this list item
      // can continue the list; otherwise, create a list container.

      data->marker_offset = parser->indent;

      if (container->type != NODE_LIST ||
          !lists_match(&container->as.list, data)) {
        container =
            add_child(parser, container, NODE_LIST, parser->first_nonspace + 1);

        memcpy(&container->as.list, data, sizeof(*data));
      }

      // add the list item
      container =
          add_child(parser, container, NODE_ITEM, parser->first_nonspace + 1);
      /* TODO: static */
      memcpy(&container->as.list, data, sizeof(*data));
      free(data);

    } else if (indented && !maybe_lazy && !parser->blank) {
      S_advance_offset(parser, &input, CODE_INDENT, true);
      container =
          add_child(parser, container, NODE_CODE_BLOCK, parser->offset + 1);
      container->as.code.fenced = false;
      container->as.code.fence_char = 0;
      container->as.code.fence_length = 0;
      container->as.code.fence_offset = 0;
      container->as.code.info = cmark_chunk_literal("");

    } else {
      break;
    }

    if (accepts_lines(container->type)) {
      // if it's a line container, it can't contain other containers
      break;
    }
    maybe_lazy = false;
  }

  // what remains at parser->offset is a text line.  add the text to the
  // appropriate container.

  S_find_first_nonspace(parser, &input);

  if (parser->blank && container->last_child) {
    container->last_child->last_line_blank = true;
  }

  // block quote lines are never blank as they start with >
  // and we don't count blanks in fenced code for purposes of tight/loose
  // lists or breaking out of lists.  we also don't set last_line_blank
  // on an empty list item.
  container->last_line_blank =
      (parser->blank && container->type != NODE_BLOCK_QUOTE &&
       container->type != NODE_HEADER &&
       !(container->type == NODE_CODE_BLOCK && container->as.code.fenced) &&
       !(container->type == NODE_ITEM && container->first_child == NULL &&
         container->start_line == parser->line_number));

  cmark_node *cont = container;
  while (cont->parent) {
    cont->parent->last_line_blank = false;
    cont = cont->parent;
  }

  if (parser->current != last_matched_container &&
      container == last_matched_container && !parser->blank &&
      parser->current->type == NODE_PARAGRAPH &&
      cmark_strbuf_len(&parser->current->string_content) > 0) {

    add_line(parser->current, &input, parser->offset);

  } else { // not a lazy continuation

    // finalize any blocks that were not matched and set cur to container:
    while (parser->current != last_matched_container) {
      parser->current = finalize(parser, parser->current);
      assert(parser->current != NULL);
    }

    if (container->type == NODE_CODE_BLOCK) {

      add_line(container, &input, parser->offset);

    } else if (container->type == NODE_HTML) {

      add_line(container, &input, parser->offset);

      int matches_end_condition;
      switch (container->as.html_block_type) {
      case 1:
        // </script>, </style>, </pre>
        matches_end_condition =
            scan_html_block_end_1(&input, parser->first_nonspace);
        break;
      case 2:
        // -->
        matches_end_condition =
            scan_html_block_end_2(&input, parser->first_nonspace);
        break;
      case 3:
        // ?>
        matches_end_condition =
            scan_html_block_end_3(&input, parser->first_nonspace);
        break;
      case 4:
        // >
        matches_end_condition =
            scan_html_block_end_4(&input, parser->first_nonspace);
        break;
      case 5:
        // ]]>
        matches_end_condition =
            scan_html_block_end_5(&input, parser->first_nonspace);
        break;
      default:
        matches_end_condition = 0;
        break;
      }

      if (matches_end_condition) {
        container = finalize(parser, container);
        assert(parser->current != NULL);
      }

    } else if (parser->blank) {

      // ??? do nothing

    } else if (accepts_lines(container->type)) {

      if (container->type == NODE_HEADER &&
          container->as.header.setext == false) {
        chop_trailing_hashtags(&input);
      }
      add_line(container, &input, parser->first_nonspace);

    } else {
      // create paragraph container for line
      container = add_child(parser, container, NODE_PARAGRAPH,
                            parser->first_nonspace + 1);
      add_line(container, &input, parser->first_nonspace);
    }

    parser->current = container;
  }
finished:
  parser->last_line_length = parser->curline->size;
  if (parser->last_line_length &&
      parser->curline->ptr[parser->last_line_length - 1] == '\n')
    parser->last_line_length -= 1;
  if (parser->last_line_length &&
      parser->curline->ptr[parser->last_line_length - 1] == '\r')
    parser->last_line_length -= 1;

  cmark_strbuf_clear(parser->curline);
}

cmark_node *cmark_parser_finish(cmark_parser *parser) {
  if (parser->linebuf->size) {
    S_process_line(parser, parser->linebuf->ptr, parser->linebuf->size);
    cmark_strbuf_clear(parser->linebuf);
  }

  finalize_document(parser);

  if (parser->options & CMARK_OPT_NORMALIZE) {
    cmark_consolidate_text_nodes(parser->root);
  }

  cmark_strbuf_free(parser->curline);

#if CMARK_DEBUG_NODES
  if (cmark_node_check(parser->root, stderr)) {
    abort();
  }
#endif
  return parser->root;
}
