/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief doubly-linked list tests
 *
 * @defgroup lib_dlist_tests Dlist
 */

#include <ztest.h>
#include <sys/dlist.h>

#define NODE_SIZE 5

static sys_dlist_t test_list;

struct container_node {
	sys_dnode_t node;
	int value;
};

/**
 * @brief Test whether dlist node struct is embeddedable
 * in any user structure
 *
 * @details Initialize an user defined structure contains
 * dlist node.Appending nodes into the doubly-linked list
 * and enumerate the doubly-linked list.
 *
 * Verify that the value enumerated is equal to the
 * value initialized.If the verification pass,the user
 * defined structure works.
 *
 * @ingroup lib_dlist_tests
 *
 * @see sys_dlist_append()
 */

void test_dlist_container(void)
{
	int i, count;
	struct container_node *cnode, *s_cnode;

	/* Initialize an user-defiend structure of contains dlist node */
	struct container_node data_node[NODE_SIZE] = {
		{ .value = 0 },
		{ .value = 1 },
		{ .value = 2 },
		{ .value = 3 },
		{ .value = 4 }
	};

	sys_dlist_init(&test_list);
	zassert_true(sys_dlist_is_empty(&test_list),
			"sys_dlist_init failed");

	/* Add into a doubly-linked list */
	for (i = 0; i < NODE_SIZE; i++) {
		sys_dlist_append(&test_list, &data_node[i].node);
	}

	/* Enumerate the doubly-linked list */
	count = 0;
	SYS_DLIST_FOR_EACH_CONTAINER(&test_list, cnode, node) {
		zassert_true(cnode->value == count,
				"SYS_DLIST_FOR_EACH_CONTAINER failed");
		count++;
	}
	zassert_true(count == NODE_SIZE,
			"SYS_DLIST_FOR_EACH_CONTAINER failed "
			"expected %d get %d", NODE_SIZE, count);

	/* Enumerate the doubly-linked list */
	count = 0;
	SYS_DLIST_FOR_EACH_CONTAINER_SAFE(&test_list, cnode, s_cnode, node) {
		zassert_true(cnode->value == count,
				"SYS_DLIST_FOR_EACH_CONTAINER_SAFE failed");
		count++;
	}
	zassert_true(count == NODE_SIZE,
			"SYS_DLIST_FOR_EACH_CONTAINER_SAFE failed");
}

/**
 * @brief Test dlist for each function
 *
 * @details Initialize a double-linked list.
 * Appending nodes into the doubly-linked list
 * and enumerate the doubly-linked list.
 *
 * Verify that the value enumerated is equal to the
 * value initialized.If the verification pass,the "for each"
 * style API work.
 *
 * @ingroup lib_dlist_tests
 *
 * @see SYS_DLIST_FOR_EACH_NODE(),SYS_DLIST_FOR_EACH_NODE_SAFE()
 * SYS_DLIST_ITERATE_FROM_NODE()
 */

void test_dlist_for_each(void)
{
	int i, count, val;
	sys_dnode_t *node, *s_node;

	/* Initialize a doubly-linked list */
	struct container_node data_node[NODE_SIZE] = {
		{ .value = 0 },
		{ .value = 1 },
		{ .value = 2 },
		{ .value = 3 },
		{ .value = 4 }
	};

	sys_dlist_init(&test_list);
	zassert_true(sys_dlist_is_empty(&test_list),
			"sys_dlist_init failed");

	for (i = 0; i < NODE_SIZE; i++) {
		sys_dlist_append(&test_list, &data_node[i].node);
	}

	/* Enumerate the doubly-linked list */
	count = 0;
	SYS_DLIST_FOR_EACH_NODE(&test_list, node) {
		val = CONTAINER_OF(node, struct container_node, node)->value;
		zassert_true(val == count, "SYS_DLIST_FOR_EACH_NODE failed"
				" expected %d get %d", count, val);
		count++;
	}
	zassert_true(count == NODE_SIZE,
			"SYS_DLIST_FOR_EACH_NODE failed");

	/* Enumerate the doubly-linked list */
	count = 0;
	SYS_DLIST_FOR_EACH_NODE_SAFE(&test_list, node, s_node) {
		val = CONTAINER_OF(node, struct container_node, node)->value;
		zassert_true(val == count, "SYS_DLIST_FOR_EACH_NODE_SAFE failed"
				" expected %d get %d", count, val);
		count++;
	}
	zassert_true(count == NODE_SIZE,
			"SYS_DLIST_FOR_EACH_NODE_SAFE failed");

	/* Enumerate the doubly-linked list */
	count = 0;
	SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
		count++;
		val = ((struct container_node *)node)->value;
		if (val == 1) {
			break;
		}
	}
	zassert_true(count == 2, "SYS_DLIST_ITERATE_FROM_NODE failed");

	count = 0;
	SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
		count++;
		val = ((struct container_node *)node)->value;
		if (val == 2) {
			break;
		}
	}
	zassert_true(count == 1, "SYS_DLIST_ITERATE_FROM_NODE failed");

	count = 0;
	SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
		count++;
	}
	zassert_true(count == 2, "SYS_DLIST_ITERATE_FROM_NODE failed");
}

/**
 * @brief Test that access the 'head' and 'tail' in constant time
 *
 * @details Defined a double list and append several nodes.
 * defined two pointers---'head','tail'.No matter how many nodes
 * dlist have, get head and tail from the dlist directly.the time
 * complexity of accessing head and tail is O(1).
 *
 * @ingroup lib_dlist_tests
 */
void test_dlist_peak_head_tail(void)
{
	sys_dlist_t list;
	sys_dnode_t node[10];
	sys_dnode_t *head, *tail;

	sys_dlist_init(&list);

	for (int i = 0; i < ARRAY_SIZE(node); i++) {
		sys_dlist_append(&list, &node[i]);
	}

	/* Get 'head' node directly, the time complexity is O(1) */
	head = list.head;
	zassert_true(head == &node[0],
			"dlist can't access 'head' in constant time");

	/* Get 'tail' node directly, the time complexity is O(1) */
	tail = list.tail;
	zassert_true(tail == &node[ARRAY_SIZE(node) - 1],
			"dlist can't access 'tail' in constant time");
}

/**
 * @brief Test that insert or remove operates in constant time
 *
 * @details Defined a double list and append several nodes that
 * a node has two pointers 'pre' and 'next' in pointer area.
 * And define a node to be ready for inserting or removing,
 * 'insert' and 'remove' are the operations with fixed steps and
 * no matter the size of a dlist.
 * Verify that the operations are running in constant time by
 * proving the time complexity is O(1).
 *
 * @ingroup lib_dlist_tests
 */
void test_dlist_insert_and_remove(void)
{
	sys_dlist_t list;
	sys_dlist_t node[10];

	sys_dlist_init(&list);

	for (int i = 0; i < ARRAY_SIZE(node); i++) {
		sys_dlist_append(&list, &node[i]);
	}

	sys_dnode_t node_ins, *insert_at = &node[ARRAY_SIZE(node)/2];
	sys_dnode_t *insert_node = &node_ins;

	/* Insert a node and steps are fixed,the time complexity is O(1) */
	insert_node->prev = insert_at->prev;
	insert_node->next = insert_at;
	insert_at->prev->next = insert_node;
	insert_at->prev = insert_node;
	/*Check if the node is inserted successfully*/
	zassert_true(insert_node == sys_dlist_peek_prev(&list,
		&node[ARRAY_SIZE(node)/2]), "dlist can't insert a node in constant time");
	zassert_true(insert_node == sys_dlist_peek_next(&list,
		&node[ARRAY_SIZE(node)/2 - 1]), "dlist can't insert a node in constant time");

	/* Remove a node and steps are fixed,the time complexity is O(1) */
	insert_node->prev->next = insert_node->next;
	insert_node->next->prev = insert_node->prev;
	/*Check if the node is removed successfully*/
	zassert_true(insert_node != sys_dlist_peek_prev(&list,
		&node[ARRAY_SIZE(node)/2]), "dlist can't insert a node in constant time");
	zassert_true(insert_node != sys_dlist_peek_next(&list,
		&node[ARRAY_SIZE(node)/2 - 1]), "dlist can't remove a node in constant time");
}

/* ztest main entry */
void test_main(void)
{
	ztest_test_suite(test_dlist,
			ztest_unit_test(test_dlist_container),
			ztest_unit_test(test_dlist_for_each),
			ztest_unit_test(test_dlist_peak_head_tail),
			ztest_unit_test(test_dlist_insert_and_remove)
			);
	ztest_run_test_suite(test_dlist);
}
