/* SPDX-License-Identifier: GPL-2.0-only */

#include <tests/test.h>
#include <stdlib.h>
#include <string.h>
#include <list.h>

struct test_container {
	int value;

	struct list_node list_node;
};

void test_list_insert_after(void **state)
{
	int i = 0;
	struct list_node root = { .prev = NULL, .next = NULL };
	struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1));
	struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2));
	struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2));
	struct test_container *ptr;
	const int values[] = { 5, 10, 13 }; /* Random values */

	memset(c1, 0, sizeof(*c1));
	memset(c2, 0, sizeof(*c2));
	memset(c2, 0, sizeof(*c3));

	c1->value = values[0];
	c2->value = values[1];
	c3->value = values[2];

	list_insert_after(&c1->list_node, &root);
	list_insert_after(&c2->list_node, &c1->list_node);
	list_insert_after(&c3->list_node, &c2->list_node);

	list_for_each(ptr, root, list_node) {
		assert_int_equal(values[i], ptr->value);
		i++;
	}

	assert_int_equal(3, i);

	free(c3);
	free(c2);
	free(c1);
}

void test_list_insert_before(void **state)
{
	int i = 0;
	struct list_node root = { .prev = NULL, .next = NULL };
	struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1));
	struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2));
	struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2));
	struct test_container *ptr;
	const int values[] = { 19, 71, 991  }; /* Random values */

	memset(c1, 0, sizeof(*c1));
	memset(c2, 0, sizeof(*c2));
	memset(c2, 0, sizeof(*c3));

	c1->value = values[0];
	c2->value = values[1];
	c3->value = values[2];

	list_insert_after(&c3->list_node, &root);
	list_insert_before(&c2->list_node, &c3->list_node);
	list_insert_before(&c1->list_node, &c2->list_node);


	list_for_each(ptr, root, list_node) {
		assert_int_equal(values[i], ptr->value);
		i++;
	}

	assert_int_equal(3, i);

	free(c3);
	free(c2);
	free(c1);
}

void test_list_remove(void **state)
{
	struct list_node root = { .prev = NULL, .next = NULL };
	struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1));
	struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2));
	struct test_container *ptr;
	int len;

	list_insert_after(&c1->list_node, &root);
	list_insert_after(&c2->list_node, &c1->list_node);

	len = 0;
	list_for_each(ptr, root, list_node) {
		len++;
	}
	assert_int_equal(2, len);

	list_remove(&c1->list_node);

	len = 0;
	list_for_each(ptr, root, list_node) {
		len++;
	}
	assert_int_equal(1, len);

	list_remove(&c2->list_node);
	len = 0;
	list_for_each(ptr, root, list_node) {
		len++;
	}
	assert_int_equal(0, len);

	free(c2);
	free(c1);
}

void test_list_append(void **state)
{
	size_t idx;
	struct test_container *node;
	struct list_node root = {};
	struct test_container nodes[] = {
		{1}, {2}, {3}
	};

	for (idx = 0; idx < ARRAY_SIZE(nodes); ++idx)
		list_append(&nodes[idx].list_node, &root);

	idx = 0;
	list_for_each(node, root, list_node) {
		assert_ptr_equal(node, &nodes[idx]);
		idx++;
	}
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test(test_list_insert_after),
		cmocka_unit_test(test_list_insert_before),
		cmocka_unit_test(test_list_remove),
		cmocka_unit_test(test_list_append),
	};


	return cb_run_group_tests(tests, NULL, NULL);
}
