#include "cmark.h"
#include "utf8.h"
#include "parser.h"
#include "references.h"
#include "inlines.h"
#include "chunk.h"

static unsigned int refhash(const unsigned char *link_ref) {
  unsigned int hash = 0;

  while (*link_ref)
    hash = (*link_ref++) + (hash << 6) + (hash << 16) - hash;

  return hash;
}

static void reference_free(cmark_reference *ref) {
  if (ref != NULL) {
    free(ref->label);
    cmark_chunk_free(&ref->url);
    cmark_chunk_free(&ref->title);
    free(ref);
  }
}

// normalize reference:  collapse internal whitespace to single space,
// remove leading/trailing whitespace, case fold
// Return NULL if the reference name is actually empty (i.e. composed
// solely from whitespace)
static unsigned char *normalize_reference(cmark_chunk *ref) {
  cmark_strbuf normalized = GH_BUF_INIT;
  unsigned char *result;

  if (ref == NULL)
    return NULL;

  if (ref->len == 0)
    return NULL;

  cmark_utf8proc_case_fold(&normalized, ref->data, ref->len);
  cmark_strbuf_trim(&normalized);
  cmark_strbuf_normalize_whitespace(&normalized);

  result = cmark_strbuf_detach(&normalized);
  assert(result);

  if (result[0] == '\0') {
    free(result);
    return NULL;
  }

  return result;
}

static void add_reference(cmark_reference_map *map, cmark_reference *ref) {
  cmark_reference *t = ref->next = map->table[ref->hash % REFMAP_SIZE];

  while (t) {
    if (t->hash == ref->hash && !strcmp((char *)t->label, (char *)ref->label)) {
      reference_free(ref);
      return;
    }

    t = t->next;
  }

  map->table[ref->hash % REFMAP_SIZE] = ref;
}

void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label,
                            cmark_chunk *url, cmark_chunk *title) {
  cmark_reference *ref;
  unsigned char *reflabel = normalize_reference(label);

  /* empty reference name, or composed from only whitespace */
  if (reflabel == NULL)
    return;

  ref = (cmark_reference *)calloc(1, sizeof(*ref));
  if (ref != NULL) {
    ref->label = reflabel;
    ref->hash = refhash(ref->label);
    ref->url = cmark_clean_url(url);
    ref->title = cmark_clean_title(title);
    ref->next = NULL;

    add_reference(map, ref);
  }
}

// Returns reference if refmap contains a reference with matching
// label, otherwise NULL.
cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
                                        cmark_chunk *label) {
  cmark_reference *ref = NULL;
  unsigned char *norm;
  unsigned int hash;

  if (label->len > MAX_LINK_LABEL_LENGTH)
    return NULL;

  if (map == NULL)
    return NULL;

  norm = normalize_reference(label);
  if (norm == NULL)
    return NULL;

  hash = refhash(norm);
  ref = map->table[hash % REFMAP_SIZE];

  while (ref) {
    if (ref->hash == hash && !strcmp((char *)ref->label, (char *)norm))
      break;
    ref = ref->next;
  }

  free(norm);
  return ref;
}

void cmark_reference_map_free(cmark_reference_map *map) {
  unsigned int i;

  if (map == NULL)
    return;

  for (i = 0; i < REFMAP_SIZE; ++i) {
    cmark_reference *ref = map->table[i];
    cmark_reference *next;

    while (ref) {
      next = ref->next;
      reference_free(ref);
      ref = next;
    }
  }

  free(map);
}

cmark_reference_map *cmark_reference_map_new(void) {
  return (cmark_reference_map *)calloc(1, sizeof(cmark_reference_map));
}
