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

#include "doubly-linked-list.h"

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif

#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif

/* Implementation */

typedef int T;

typedef struct ListNodeType
{
  T value;
  struct ListNodeType *next;
  struct ListNodeType *prev;
} ListNodeType;

ListNodeType * l_new_node (T value)
{
  ListNodeType *n = malloc (sizeof (ListNodeType));
  n->next = NULL;
  n->prev = NULL;
  n->value = value;
  return n;
}

typedef struct LinkedListWrapperType
{
  ListNodeType *first;
  ListNodeType *last;
  size_t size;
} LinkedListWrapperType;

int compare_nodes (const ListNodeType *n1, const ListNodeType *n2)
{
  if (n1->value == n2->value)
    return 0;
  else if (n1->value < n2->value)
    return -1;
  else
    return 1;
}

LINKED_LIST_MUTATIVE_OPS_PROTOTYPE (LinkedListWrapperType, ListNodeType, static);
LINKED_LIST_MERGE_SORT_PROTOTYPE (LinkedListWrapperType, ListNodeType, static);

LINKED_LIST_MUTATIVE_OPS_DECL (LinkedListWrapperType, ListNodeType, static)
LINKED_LIST_MERGE_SORT_DECL (LinkedListWrapperType, ListNodeType, static)

ListNodeType * find_last_node (ListNodeType *head)
{
  if (head == NULL)
    return NULL;

  ListNodeType *n = head;
  while (n->next != NULL)
    n = n->next;

  return n;
}

void l_print (ListNodeType *node)
{
  for (ListNodeType *l = node; l != NULL; l = l->next)
    printf ("%d ", l->value);
  printf ("\n");
}

void l_reverse_print (ListNodeType *last_node)
{
  for (ListNodeType *l = last_node; l != NULL; l = l->prev)
    printf ("%d ", l->value);
  printf ("\n");
}

struct test_data_t
{
  T const *content;
  size_t size;
};

bool run_test (const struct test_data_t *expect,
	       LinkedListWrapperType *current,
	       bool reversed)
{
  ListNodeType *node = (reversed) ? current->last : current->first;
  bool passed = true;
  for (int i=0; i<expect->size && node != NULL; ++i)
    {
      if (reversed)
	{
	  if (expect->content[expect->size - 1 - i] != node->value)
	    {
	      printf ("FAIL: mismatching expected (%d) VS current (%d).\n",
		      expect->content[expect->size - 1 - i], node->value);
	      passed = false;
	    }
	  if (node->prev == NULL && current->first != node)
	    {
	      printf ("FAIL: first is not matching the first node.\n");
	      passed = false;
	    }
	}
      else
	{
	  if (expect->content[i] != node->value)
	    {
	      printf ("FAIL: mismatching expected (%d) VS current (%d).\n",
		      expect->content[i], node->value);
	      passed = false;
	    }
	  if (node->next == NULL && current->last != node)
	    {
	      printf ("FAIL: last_ is not matching the last node.\n");
	      passed = false;
	    }
	}

      if (!passed)
	return false;

      if (reversed)
	node = node->prev;
      else
	node = node->next;
    }

  if (node != NULL)
    {
      printf ("FAIL: the list is longer than expected.\n");
      passed = false;
    }
  if (expect->size != current->size)
    {
      printf ("FAIL: size (%ld) is not matching the real size of the list (%ld).\n",
	      current->size, expect->size);
      passed = false;
    }

  return passed;
}

bool check(const char *op,
	  const struct test_data_t *expect,
	  LinkedListWrapperType *wrapper)
{
  bool success = true;
  bool res;

#define DUMP_LIST 0

  if (DUMP_LIST)
    l_print (wrapper->first);

  res = run_test (expect, wrapper, false);
  printf ("%s: test-linked-list::%s: check forward conformity\n",
	  res ? "PASS": "FAIL", op);
  success &= res;

  if (DUMP_LIST)
    l_reverse_print (wrapper->last);

  res = run_test (expect, wrapper, true);
  printf ("%s: test-linked-list::%s: check backward conformity\n",
	  res ? "PASS": "FAIL", op);
  success &= res;

  if (DUMP_LIST)
    printf("\n");

  return success;
}

const int EXPECT_0 [] = { 10, 4, 3, 1, 9, 2 };
const int EXPECT_1 [] = { 1, 2, 3, 4, 9, 10 };
const int EXPECT_2 [] = { 11, 1, 2, 3, 4, 9, 10 };
const int EXPECT_3 [] = { 11, 1, 2, 3, 4, 9, 8, 10 };
const int EXPECT_4 [] = { 11, 2, 3, 4, 9, 8, 10 };
const int EXPECT_5 [] = { 10, 2, 3, 4, 9, 8, 11 };
const int EXPECT_6 [] = { 10, 3, 2, 4, 9, 8, 11 };
const int EXPECT_7 [] = { 10, 9, 2, 4, 3, 8, 11 };
const int EXPECT_8 [] = { 2, 3, 4, 8, 9, 10, 11 };
const int EXPECT_9 [] = { 3, 4, 8, 9, 10, 11 };
const int EXPECT_10 [] = { 3, 4, 8, 9, 10 };
const struct test_data_t test_data[] = {
  { .content = EXPECT_0, .size = sizeof(EXPECT_0) / sizeof(EXPECT_0[0]) },
  { .content = EXPECT_1, .size = sizeof(EXPECT_1) / sizeof(EXPECT_1[0]) },
  { .content = EXPECT_2, .size = sizeof(EXPECT_2) / sizeof(EXPECT_2[0]) },
  { .content = EXPECT_3, .size = sizeof(EXPECT_3) / sizeof(EXPECT_3[0]) },
  { .content = EXPECT_4, .size = sizeof(EXPECT_4) / sizeof(EXPECT_4[0]) },
  { .content = EXPECT_5, .size = sizeof(EXPECT_5) / sizeof(EXPECT_5[0]) },
  { .content = EXPECT_6, .size = sizeof(EXPECT_6) / sizeof(EXPECT_6[0]) },
  { .content = EXPECT_7, .size = sizeof(EXPECT_7) / sizeof(EXPECT_7[0]) },
  { .content = EXPECT_8, .size = sizeof(EXPECT_8) / sizeof(EXPECT_8[0]) },
  { .content = EXPECT_9, .size = sizeof(EXPECT_9) / sizeof(EXPECT_9[0]) },
  { .content = EXPECT_10, .size = sizeof(EXPECT_10) / sizeof(EXPECT_10[0]) },
};

int main (void)
{
  int failures = 0;

  LinkedListWrapperType wrapper = {
    .first = NULL,
    .last = NULL,
    .size = 0,
  };

  /* Append nodes.  */
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (10));
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (4));
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (3));
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (1));
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (9));
  LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (2));

  failures += ! check ("append", &test_data[0], &wrapper);

  /* Sort nodes (without updating wrapper).  */
  wrapper.first =
    LINKED_LIST_MERGE_SORT_(ListNodeType) (wrapper.first, compare_nodes);
  wrapper.last = find_last_node (wrapper.first);

  failures += ! check ("sort", &test_data[1], &wrapper);

  /* Save a reference to this node for later.  */
  ListNodeType *n_to_remove = wrapper.first;

  /* Prepend node.  */
  LINKED_LIST_PREPEND(ListNodeType) (&wrapper, l_new_node (11));
  failures += ! check ("prepend", &test_data[2], &wrapper);

  /* Insert node.  */
  LINKED_LIST_INSERT_BEFORE(ListNodeType) (&wrapper, l_new_node (8), wrapper.last);
  failures += ! check ("insert_before", &test_data[3], &wrapper);

  /* Remove a node.  */
  LINKED_LIST_REMOVE(ListNodeType) (&wrapper, n_to_remove);
  failures += ! check ("remove", &test_data[4], &wrapper);

  /* Swap first and last.  */
  LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first, wrapper.last);
  failures += ! check ("swap first and last", &test_data[5], &wrapper);

  /* Swap adjacent nodes.  */
  LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next,
				  wrapper.first->next->next);
  failures += ! check ("swap adjacent nodes", &test_data[6], &wrapper);

  /* Swap non-adjacent nodes, but neither first nor last.  */
  LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next,
				  wrapper.first->next->next->next->next);
  failures += ! check ("swap non-adjacent nodes", &test_data[7], &wrapper);

  /* Sort nodes.  */
  LINKED_LIST_MERGE_SORT(ListNodeType) (&wrapper, compare_nodes);
  failures += ! check ("sort", &test_data[8], &wrapper);

  /* Pop front.  */
  LINKED_LIST_POP_FRONT(ListNodeType) (&wrapper);
  failures += ! check ("pop_front", &test_data[9], &wrapper);

  /* Pop back.  */
  LINKED_LIST_POP_BACK(ListNodeType) (&wrapper);
  failures += ! check ("pop_back", &test_data[10], &wrapper);

  exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
}
