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

#include <zephyr/ztest.h>
#include <zephyr/sys/sflist.h>

static sys_sflist_t test_list;
static sys_sflist_t append_list;

struct container_node {
	sys_sfnode_t node;
	int unused;
};

static struct container_node test_node_1;
static struct container_node test_node_2;
static struct container_node test_node_3;
static struct container_node test_node_4;

static inline bool verify_emptyness(sys_sflist_t *list)
{
	sys_sfnode_t *node;
	sys_sfnode_t *s_node;
	struct container_node *cnode;
	struct container_node *s_cnode;
	int count;

	if (!sys_sflist_is_empty(list)) {
		return false;
	}

	if (sys_sflist_peek_head(list)) {
		return false;
	}

	if (sys_sflist_peek_tail(list)) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_NODE(list, node) {
		count++;
	}

	if (count) {
		return false;
	}

	SYS_SFLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
		count++;
	}

	if (count) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_CONTAINER(list, cnode, node) {
		count++;
	}

	if (count) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
		count++;
	}

	if (count) {
		return false;
	}

	return true;
}

static inline bool verify_content_amount(sys_sflist_t *list, int amount)
{
	sys_sfnode_t *node;
	sys_sfnode_t *s_node;
	struct container_node *cnode;
	struct container_node *s_cnode;
	int count;

	if (sys_sflist_is_empty(list)) {
		return false;
	}

	if (!sys_sflist_peek_head(list)) {
		return false;
	}

	if (!sys_sflist_peek_tail(list)) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_NODE(list, node) {
		count++;
	}

	if (count != amount) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
		count++;
	}

	if (count != amount) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_CONTAINER(list, cnode, node) {
		count++;
	}

	if (count != amount) {
		return false;
	}

	count = 0;
	SYS_SFLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
		count++;
	}

	if (count != amount) {
		return false;
	}

	return true;
}

static inline bool verify_tail_head(sys_sflist_t *list,
				    sys_sfnode_t *head,
				    sys_sfnode_t *tail,
				    bool same)
{
	if (sys_sflist_peek_head(list) != head) {
		return false;
	}

	if (sys_sflist_peek_tail(list) != tail) {
		return false;
	}

	if (same) {
		if (sys_sflist_peek_head(list) != sys_sflist_peek_tail(list)) {
			return false;
		}
	} else {
		if (sys_sflist_peek_head(list) == sys_sflist_peek_tail(list)) {
			return false;
		}
	}

	return true;
}
/**
 * @addtogroup kernel_common_tests
 * @{
 */

/**
 * @brief Test singly linked list functionalities
 *
 * @details Test list initialization, append item to the list,
 * find and remove item, prepend, append, remove list
 *
 * @see sys_sflist_init(), sys_sflist_append(),
 * sys_sflist_find_and_remove(), sys_sflist_prepend(),
 * sys_sflist_remove(), sys_sflist_get(), sys_sflist_get_not_empty(),
 * sys_sflist_append_list(), sys_sflist_merge_list()
 */
ZTEST(dlist_api, test_sflist)
{
	sys_sflist_init(&test_list);

	zassert_true((verify_emptyness(&test_list)),
		      "test_list should be empty");

	/* Appending node 1 */
	sys_sflist_append(&test_list, &test_node_1.node);
	zassert_true((verify_content_amount(&test_list, 1)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_1.node,
				       &test_node_1.node, true)),
		     "test_list head/tail are wrong");

	/* Finding and removing node 1 */
	sys_sflist_find_and_remove(&test_list, &test_node_1.node);
	zassert_true((verify_emptyness(&test_list)),
		     "test_list should be empty");

	/* Prepending node 1 */
	sys_sflist_prepend(&test_list, &test_node_1.node);
	zassert_true((verify_content_amount(&test_list, 1)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_1.node,
				       &test_node_1.node, true)),
		     "test_list head/tail are wrong");

	/* Removing node 1 */
	sys_sflist_remove(&test_list, NULL, &test_node_1.node);
	zassert_true((verify_emptyness(&test_list)),
		     "test_list should be empty");

	/* Appending node 1 */
	sys_sflist_append(&test_list, &test_node_1.node);
	/* Prepending node 2 */
	sys_sflist_prepend(&test_list, &test_node_2.node);

	zassert_true((verify_content_amount(&test_list, 2)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_1.node, false)),
		     "test_list head/tail are wrong");

	/* Appending node 3 */
	sys_sflist_append(&test_list, &test_node_3.node);

	zassert_true((verify_content_amount(&test_list, 3)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_3.node, false)),
		     "test_list head/tail are wrong");

	zassert_true((sys_sflist_peek_next(&test_node_2.node) ==
		      &test_node_1.node),
		     "test_list node links are wrong");

	/* Inserting node 4 after node 2, peek with nocheck variant */
	sys_sflist_insert(&test_list, &test_node_2.node, &test_node_4.node);

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_3.node, false)),
		     "test_list head/tail are wrong");

	zassert_true((sys_sflist_peek_next_no_check(&test_node_2.node) ==
		      &test_node_4.node),
		     "test_list node links are wrong");

	/* Finding and removing node 1 */
	sys_sflist_find_and_remove(&test_list, &test_node_1.node);
	zassert_true((verify_content_amount(&test_list, 3)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_3.node, false)),
		     "test_list head/tail are wrong");

	/* Removing node 3 */
	sys_sflist_remove(&test_list, &test_node_4.node, &test_node_3.node);
	zassert_true((verify_content_amount(&test_list, 2)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_4.node, false)),
		     "test_list head/tail are wrong");

	/* Removing node 4 */
	sys_sflist_remove(&test_list, &test_node_2.node, &test_node_4.node);
	zassert_true((verify_content_amount(&test_list, 1)),
		     "test_list has wrong content");

	zassert_true((verify_tail_head(&test_list, &test_node_2.node,
				       &test_node_2.node, true)),
		     "test_list head/tail are wrong");

	/* Removing node 2 */
	sys_sflist_remove(&test_list, NULL, &test_node_2.node);
	zassert_true((verify_emptyness(&test_list)),
		     "test_list should be empty");

	/* test iterator from a node */
	struct data_node {
		sys_sfnode_t node;
		int data;
	} data_node[6] = {
		{ .data = 0 },
		{ .data = 1 },
		{ .data = 2 },
		{ .data = 3 },
		{ .data = 4 },
		{ .data = 5 },
	};
	sys_sfnode_t *node = NULL;
	int ii;

	sys_sflist_init(&test_list);

	for (ii = 0; ii < 6; ii++) {
		sys_sflist_append(&test_list, &data_node[ii].node);
	}

	ii = 0;
	SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
		ii++;
		if (((struct data_node *)node)->data == 2) {
			break;
		}
	}
	zassert_equal(ii, 3, "");

	ii = 0;
	SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
		ii++;
		if (((struct data_node *)node)->data == 3) {
			break;
		}
	}
	zassert_equal(ii, 1, "");

	ii = 0;
	SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
		ii++;
	}
	zassert_equal(ii, 2, "");

	/* test sys_sflist_get_not_empty() and sys_sflist_get() APIs */
	for (ii = 0; ii < 6; ii++) {
		node = sys_sflist_get_not_empty(&test_list);
		zassert_equal(((struct data_node *)node)->data, ii, "");
	}
	for (ii = 0; ii < 6; ii++) {
		/* regenerate test_list since we just emptied it */
		sys_sflist_append(&test_list, &data_node[ii].node);
	}
	for (ii = 0; ii < 6; ii++) {
		node = sys_sflist_get(&test_list);
		zassert_equal(((struct data_node *)node)->data, ii, "");
	}
	node = sys_sflist_get(&test_list);
	zassert_equal(node, NULL, "");

	/* test sys_sflist_append_list() */
	sys_sflist_init(&append_list);
	struct data_node data_node_append[6] = {
		{ .data = 6 },
		{ .data = 7 },
		{ .data = 8 },
		{ .data = 9 },
		{ .data = 10 },
		{ .data = 11 },
	};
	for (ii = 0; ii < 6; ii++) {
		/* regenerate test_list, which we just emptied */
		sys_sflist_append(&test_list, &data_node[ii].node);
		/* Build append_list so that the node pointers are correct */
		sys_sflist_append(&append_list, &data_node_append[ii].node);
	}
	sys_sflist_append_list(&test_list, &data_node_append[0].node,
			      &data_node_append[5].node);
	for (ii = 0; ii < 12; ii++) {
		node = sys_sflist_get(&test_list);
		zassert_equal(((struct data_node *)node)->data, ii,
			      "expected %d got %d", ii,
			      ((struct data_node *)node)->data);
	}

	/* test sys_sflist_merge_sflist */
	sys_sflist_init(&test_list);
	sys_sflist_init(&append_list);
	for (ii = 0; ii < 6; ii++) {
		/* regenerate both lists */
		sys_sflist_append(&test_list, &data_node[ii].node);
		sys_sflist_append(&append_list, &data_node_append[ii].node);
	}
	sys_sflist_merge_sflist(&test_list, &append_list);
	for (ii = 0; ii < 12; ii++) {
		node = sys_sflist_get(&test_list);
		zassert_equal(((struct data_node *)node)->data, ii,
			      "expected %d got %d", ii,
			      ((struct data_node *)node)->data);
	}
	zassert_true(sys_sflist_is_empty(&append_list),
		     "merged list is not empty");

	/* tests for sys_sfnode_flags_get(), sys_sfnode_flags_set()
	 * sys_sfnode_init()
	 */
	sys_sflist_init(&test_list);
	/* Only iterating 0..3 due to limited range of flag values */
	for (ii = 0; ii < 4; ii++) {
		sys_sfnode_init(&data_node[ii].node, ii);
		sys_sflist_append(&test_list, &data_node[ii].node);
	}
	for (ii = 0; ii < 4; ii++) {
		node = sys_sflist_get(&test_list);
		zassert_equal(sys_sfnode_flags_get(node), ii,
			      "wrong flags value");
		/* Place the nodes back on the list with the flags set
		 * in reverse order for the next test
		 */
		sys_sfnode_flags_set(node, 3 - ii);
		sys_sflist_append(&test_list, node);
	}
	for (ii = 3; ii >= 0; ii--) {
		node = sys_sflist_get(&test_list);
		zassert_equal(sys_sfnode_flags_get(node), ii,
			      "wrong flags value");
	}
}

/**
 * @}
 */
