/*
 * Copyright (c) 2022 GARDENA GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "lwm2m_engine.h"
#include "lwm2m_util.h"

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#define TEST_VERBOSE 0

#if TEST_VERBOSE
#define TEST_VERBOSE_PRINT(fmt, ...) TC_PRINT(fmt, ##__VA_ARGS__)
#else
#define TEST_VERBOSE_PRINT(fmt, ...)
#endif

static bool lwm2m_path_object_equal_upto(struct lwm2m_obj_path *path,
					 struct lwm2m_obj_path *compare_path, uint8_t level)
{

	if (level >= LWM2M_PATH_LEVEL_OBJECT && path->obj_id != compare_path->obj_id) {
		return false;
	}

	if (level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
		path->obj_inst_id != compare_path->obj_inst_id) {
		return false;
	}

	if (level >= LWM2M_PATH_LEVEL_RESOURCE && path->res_id != compare_path->res_id) {
		return false;
	}

	if (level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
		path->res_inst_id != compare_path->res_inst_id) {
		return false;
	}

	return true;
}

static void assert_path_list_order(sys_slist_t *lwm2m_path_list)
{

	struct lwm2m_obj_path_list *prev = NULL;
	struct lwm2m_obj_path_list *entry, *tmp;

	uint16_t obj_id_max;
	uint16_t obj_inst_id_max;
	uint16_t res_id_max;
	uint16_t res_inst_id_max;

	char next_path_str[LWM2M_MAX_PATH_STR_SIZE];
	char prev_path_str[LWM2M_MAX_PATH_STR_SIZE];

	if (sys_slist_is_empty(lwm2m_path_list)) {
		return;
	}

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(lwm2m_path_list, entry, tmp, node) {
		if (prev) {
			if (entry->path.level > prev->path.level) {

				lwm2m_path_to_string(next_path_str, sizeof(next_path_str),
							 &entry->path, entry->path.level);
				lwm2m_path_to_string(prev_path_str, sizeof(prev_path_str),
							 &prev->path, prev->path.level);

				bool is_after = false;

				if (prev->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
					is_after = entry->path.obj_id >= prev->path.obj_id;
				}
				if (is_after && prev->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
					entry->path.obj_id == prev->path.obj_id) {
					is_after =
						entry->path.obj_inst_id >= prev->path.obj_inst_id;
				}

				if (is_after && prev->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
					entry->path.obj_inst_id == prev->path.obj_inst_id) {
					is_after = entry->path.res_id >= prev->path.res_id;
				}

				if (is_after &&
					prev->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
					entry->path.res_id == prev->path.res_id) {
					is_after =
						entry->path.res_inst_id >= prev->path.res_inst_id;
				}

				zassert_true(is_after, "Next element %s must be before previous %s",
						 next_path_str, prev_path_str);
			} else if (entry->path.level == prev->path.level) {

				if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
					zassert_true(entry->path.obj_id >= obj_id_max,
							 "Next element has object %d which is smaller "
							 "than previous max object %d",
							 entry->path.obj_id, obj_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST) {
					if (!lwm2m_path_object_equal_upto(
							&entry->path, &prev->path,
							LWM2M_PATH_LEVEL_OBJECT)) {
						/* reset max id when path changed */
						obj_inst_id_max = 0;
					}

					zassert_true(entry->path.obj_inst_id >= obj_inst_id_max,
							 "Next element has object instance %d which is "
							 "smaller "
							 "than previous max object instance %d",
							 entry->path.obj_inst_id, obj_inst_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE) {
					if (!lwm2m_path_object_equal_upto(
							&entry->path, &prev->path,
							LWM2M_PATH_LEVEL_OBJECT_INST)) {
						/* reset max id when path changed */
						res_id_max = 0;
					}

					zassert_true(
						entry->path.res_id >= res_id_max,
						"Next element has resource %d which is smaller "
						"than previous max resource %d",
						entry->path.res_id, res_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST) {
					if (!lwm2m_path_object_equal_upto(
							&entry->path, &prev->path,
							LWM2M_PATH_LEVEL_RESOURCE)) {
						/* reset max id when path changed */
						res_inst_id_max = 0;
					}
					zassert_true(entry->path.res_inst_id >= res_inst_id_max,
							 "Next element has resource instance %d which "
							 "is smaller "
							 "than previous max resource instance %d",
							 entry->path.res_inst_id, res_inst_id_max);
				}

			} else { /* entry->path.level < prev->path.level */
				if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
					zassert_true(entry->path.obj_id >= obj_id_max,
							 "Next element has object %d which is smaller "
							 "than previous max object %d",
							 entry->path.obj_id, obj_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST) {
					zassert_true(entry->path.obj_inst_id >= obj_inst_id_max,
							 "Next element has object instance %d which is "
							 "smaller "
							 "than previous max object instance %d",
							 entry->path.obj_inst_id, obj_inst_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE) {
					zassert_true(
						entry->path.res_id >= res_id_max,
						"Next element has resource %d which is smaller "
						"than previous max resource %d",
						entry->path.res_id, res_id_max);
				}

				if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST) {
					zassert_true(entry->path.res_inst_id >= res_inst_id_max,
							 "Next element has resource instance %d which "
							 "is bigger "
							 "than previous max resource instance %d",
							 entry->path.res_inst_id, res_inst_id_max);
				}

				zassert_true(!lwm2m_path_object_equal_upto(
						&entry->path, &prev->path, entry->path.level),
						 "Next element equals previous up to level %d "
						 "and thus must be before previous",
						 entry->path.level);
			}
		}

		if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT) {
			obj_id_max = entry->path.obj_id;
		} else {
			obj_id_max = 0;
		}

		if (entry->path.level >= LWM2M_PATH_LEVEL_OBJECT_INST &&
			(prev == NULL || entry->path.obj_id == prev->path.obj_id)) {
			obj_inst_id_max = entry->path.obj_inst_id;
		} else {
			obj_inst_id_max = 0;
		}

		if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE &&
			(prev == NULL || entry->path.obj_id == prev->path.obj_id) &&
			(prev == NULL || entry->path.obj_inst_id == prev->path.obj_inst_id)) {
			res_id_max = entry->path.res_id;
		} else {
			res_id_max = 0;
		}

		if (entry->path.level >= LWM2M_PATH_LEVEL_RESOURCE_INST &&
			(prev == NULL || entry->path.obj_id == prev->path.obj_id) &&
			(prev == NULL || entry->path.obj_inst_id == prev->path.obj_inst_id) &&
			(prev == NULL || entry->path.res_id == prev->path.res_id)) {
			res_inst_id_max = entry->path.res_inst_id;
		} else {
			res_inst_id_max = 0;
		}

		prev = entry;
	}
}
static void print_path_list(sys_slist_t *lwm2m_path_list, const char *name)
{
	struct lwm2m_obj_path_list *entry, *tmp;

	if (name != NULL) {
		TEST_VERBOSE_PRINT("Path List %s:\n", name);
	}

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(lwm2m_path_list, entry, tmp, node) {
		char buf[LWM2M_MAX_PATH_STR_SIZE];

		lwm2m_path_to_string(buf, LWM2M_MAX_PATH_STR_SIZE, &entry->path, entry->path.level);
		TEST_VERBOSE_PRINT("- %s\n", buf);
	}
}

static void run_insertion_test(char const *insert_path_str[], int insertions_count,
				   char const *expected_path_str[])
{
	/* GIVEN: different paths */
	struct lwm2m_obj_path_list lwm2m_path_list_buf[insertions_count];
	sys_slist_t lwm2m_path_list;
	sys_slist_t lwm2m_path_free_list;
	int ret;

	lwm2m_engine_path_list_init(&lwm2m_path_list, &lwm2m_path_free_list, lwm2m_path_list_buf,
					insertions_count);

	/* WHEN: inserting each path */
	struct lwm2m_obj_path insert_path;
	char name[20];

	for (int i = 0; i < insertions_count; ++i) {
		ret = lwm2m_string_to_path(insert_path_str[i], &insert_path, '/');
		zassert_true(ret >= 0, "Conversion to path #%d failed", i);

		ret = lwm2m_engine_add_path_to_list(&lwm2m_path_list, &lwm2m_path_free_list,
							&insert_path);

		sprintf(name, "Insertion: %d", i);
		print_path_list(&lwm2m_path_list, name);
		zassert_true(ret >= 0, "Insertion #%d failed", i);
		/* THEN: path order is maintained */
		assert_path_list_order(&lwm2m_path_list);
	}

	print_path_list(&lwm2m_path_list, "Final");

	/* AND: final list matches expectation */
	struct lwm2m_obj_path_list *entry, *tmp;
	int path_num = 0;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&lwm2m_path_list, entry, tmp, node) {
		struct lwm2m_obj_path expected_path;

		lwm2m_string_to_path(expected_path_str[path_num++], &expected_path, '/');
		zassert_mem_equal(&entry->path, &expected_path, sizeof(struct lwm2m_obj_path),
				  "Path #%d did not match expectation", path_num);
	}
}

ZTEST(lwm2m_observation, test_add_path_to_list)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(2),
		LWM2M_PATH(1),
		LWM2M_PATH(1, 2),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 10),
		LWM2M_PATH(1, 1, 10, 10),
		LWM2M_PATH(1, 1, 10, 9),
		LWM2M_PATH(1, 2, 10, 11),

		LWM2M_PATH(100),

		LWM2M_PATH(41),
		LWM2M_PATH(43, 3),
		LWM2M_PATH(45, 2, 2),
		LWM2M_PATH(47, 1, 1, 1),

		LWM2M_PATH(57, 1, 1, 1),
		LWM2M_PATH(55, 2, 2),
		LWM2M_PATH(53, 3),
		LWM2M_PATH(51),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 10),
		LWM2M_PATH(1, 1, 10, 9),
		LWM2M_PATH(1, 1, 10, 10),
		LWM2M_PATH(1, 2),
		LWM2M_PATH(1, 2, 10, 11),
		LWM2M_PATH(2),
		LWM2M_PATH(41),
		LWM2M_PATH(43, 3),
		LWM2M_PATH(45, 2, 2),
		LWM2M_PATH(47, 1, 1, 1),
		LWM2M_PATH(51),
		LWM2M_PATH(53, 3),
		LWM2M_PATH(55, 2, 2),
		LWM2M_PATH(57, 1, 1, 1),
		LWM2M_PATH(100),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_inverse_non_overlapping)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(41),
		LWM2M_PATH(43, 3),
		LWM2M_PATH(45, 2, 2),
		LWM2M_PATH(47, 1, 1, 1),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(41),
		LWM2M_PATH(43, 3),
		LWM2M_PATH(45, 2, 2),
		LWM2M_PATH(47, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_inverse_non_overlapping_2)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(57, 1, 1, 1),
		LWM2M_PATH(55, 2, 2),
		LWM2M_PATH(53, 3),
		LWM2M_PATH(51),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(51),
		LWM2M_PATH(53, 3),
		LWM2M_PATH(55, 2, 2),
		LWM2M_PATH(57, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_object_before_resource_inst)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1, 1, 1, 1),
		LWM2M_PATH(1),
	};

	char const *expected_path_str[6] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_object_inst_before_resource_inst)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1, 1, 1, 1),
		LWM2M_PATH(1, 1),
	};

	char const *expected_path_str[6] = {
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_resource_before_resource_inst)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1, 1, 1, 1),
		LWM2M_PATH(1, 1, 1),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(1, 1, 1),
		LWM2M_PATH(1, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_resource_order)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(32765, 1, 6, 0),
		LWM2M_PATH(32765, 1, 6, 1),
		LWM2M_PATH(32765, 1, 6),
		LWM2M_PATH(32765, 1, 5),
		LWM2M_PATH(32765, 1, 5, 2),
		LWM2M_PATH(32765, 1, 5, 1),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(32765, 1, 5),
		LWM2M_PATH(32765, 1, 5, 1),
		LWM2M_PATH(32765, 1, 5, 2),
		LWM2M_PATH(32765, 1, 6),
		LWM2M_PATH(32765, 1, 6, 0),
		LWM2M_PATH(32765, 1, 6, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_resource_before_instance)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(32765, 1, 6, 0),
		LWM2M_PATH(32765, 1, 6, 1),
		LWM2M_PATH(32765, 1, 6),
	};

	char const *expected_path_str[6] = {
		LWM2M_PATH(32765, 1, 6),
		LWM2M_PATH(32765, 1, 6, 0),
		LWM2M_PATH(32765, 1, 6, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_resource_inverse)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1, 1, 1, 1),
		LWM2M_PATH(1, 1, 1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 1),
		LWM2M_PATH(1, 1, 1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_obj_after_resource)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 1),
		LWM2M_PATH(1, 2),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1, 1, 1),
		LWM2M_PATH(1, 2),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST(lwm2m_observation, test_add_path_to_list_duplicate)
{
	/* clang-format off */
	char const *insert_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
		LWM2M_PATH(1),
	};

	char const *expected_path_str[] = {
		LWM2M_PATH(1),
		LWM2M_PATH(1, 1),
	};
	/* clang-format on */

	run_insertion_test(insert_path_str, ARRAY_SIZE(insert_path_str), expected_path_str);
}

ZTEST_SUITE(lwm2m_observation, NULL, NULL, NULL, NULL, NULL);
