#include <base/logging.h>

#include "osi/include/allocator.h"
#include "osi/include/list.h"
#include "osi/include/osi.h"

struct list_node_t {
  struct list_node_t* next;
  void* data;
};

typedef struct list_t {
  list_node_t* head;
  list_node_t* tail;
  size_t length;
  list_free_cb free_cb;
  const allocator_t* allocator;
} list_t;

static list_node_t* list_free_node_(list_t* list, list_node_t* node);

// Hidden constructor, only to be used by the hash map for the allocation
// tracker.
// Behaves the same as |list_new|, except you get to specify the allocator.
list_t* list_new_internal(list_free_cb callback,
                          const allocator_t* zeroed_allocator) {
  list_t* list = (list_t*)zeroed_allocator->alloc(sizeof(list_t));
  if (!list) return NULL;

  list->free_cb = callback;
  list->allocator = zeroed_allocator;
  return list;
}

list_t* list_new(list_free_cb callback) {
  return list_new_internal(callback, &allocator_calloc);
}

void list_free(list_t* list) {
  if (!list) return;

  list_clear(list);
  list->allocator->free(list);
}

bool list_is_empty(const list_t* list) {
  CHECK(list != NULL);
  return (list->length == 0);
}

bool list_contains(const list_t* list, const void* data) {
  CHECK(list != NULL);
  CHECK(data != NULL);

  for (const list_node_t* node = list_begin(list); node != list_end(list);
       node = list_next(node)) {
    if (list_node(node) == data) return true;
  }

  return false;
}

size_t list_length(const list_t* list) {
  CHECK(list != NULL);
  return list->length;
}

void* list_front(const list_t* list) {
  CHECK(list != NULL);
  CHECK(!list_is_empty(list));

  return list->head->data;
}

void* list_back(const list_t* list) {
  CHECK(list != NULL);
  CHECK(!list_is_empty(list));

  return list->tail->data;
}

list_node_t* list_back_node(const list_t* list) {
  CHECK(list != NULL);
  CHECK(!list_is_empty(list));

  return list->tail;
}

bool list_insert_after(list_t* list, list_node_t* prev_node, void* data) {
  CHECK(list != NULL);
  CHECK(prev_node != NULL);
  CHECK(data != NULL);

  list_node_t* node = (list_node_t*)list->allocator->alloc(sizeof(list_node_t));
  if (!node) return false;

  node->next = prev_node->next;
  node->data = data;
  prev_node->next = node;
  if (list->tail == prev_node) list->tail = node;
  ++list->length;
  return true;
}

bool list_prepend(list_t* list, void* data) {
  CHECK(list != NULL);
  CHECK(data != NULL);

  list_node_t* node = (list_node_t*)list->allocator->alloc(sizeof(list_node_t));
  if (!node) return false;
  node->next = list->head;
  node->data = data;
  list->head = node;
  if (list->tail == NULL) list->tail = list->head;
  ++list->length;
  return true;
}

bool list_append(list_t* list, void* data) {
  CHECK(list != NULL);
  CHECK(data != NULL);

  list_node_t* node = (list_node_t*)list->allocator->alloc(sizeof(list_node_t));
  if (!node) return false;
  node->next = NULL;
  node->data = data;
  if (list->tail == NULL) {
    list->head = node;
    list->tail = node;
  } else {
    list->tail->next = node;
    list->tail = node;
  }
  ++list->length;
  return true;
}

bool list_remove(list_t* list, void* data) {
  CHECK(list != NULL);
  CHECK(data != NULL);

  if (list_is_empty(list)) return false;

  if (list->head->data == data) {
    list_node_t* next = list_free_node_(list, list->head);
    if (list->tail == list->head) list->tail = next;
    list->head = next;
    return true;
  }

  for (list_node_t *prev = list->head, *node = list->head->next; node;
       prev = node, node = node->next)
    if (node->data == data) {
      prev->next = list_free_node_(list, node);
      if (list->tail == node) list->tail = prev;
      return true;
    }

  return false;
}

void list_clear(list_t* list) {
  CHECK(list != NULL);
  for (list_node_t* node = list->head; node;)
    node = list_free_node_(list, node);
  list->head = NULL;
  list->tail = NULL;
  list->length = 0;
}

list_node_t* list_foreach(const list_t* list, list_iter_cb callback,
                          void* context) {
  CHECK(list != NULL);
  CHECK(callback != NULL);

  for (list_node_t* node = list->head; node;) {
    list_node_t* next = node->next;
    if (!callback(node->data, context)) return node;
    node = next;
  }
  return NULL;
}

list_node_t* list_begin(const list_t* list) {
  CHECK(list != NULL);
  return list->head;
}

list_node_t* list_end(UNUSED_ATTR const list_t* list) {
  CHECK(list != NULL);
  return NULL;
}

list_node_t* list_next(const list_node_t* node) {
  CHECK(node != NULL);
  return node->next;
}

void* list_node(const list_node_t* node) {
  CHECK(node != NULL);
  return node->data;
}

static list_node_t* list_free_node_(list_t* list, list_node_t* node) {
  CHECK(list != NULL);
  CHECK(node != NULL);

  list_node_t* next = node->next;

  if (list->free_cb) list->free_cb(node->data);
  list->allocator->free(node);
  --list->length;

  return next;
}
