/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include "lwm2m_engine.h"
#include "lwm2m_rw_link_format.h"

#define TEST_SSID 101
#define TEST_PMIN 5
#define TEST_PMAX 200

#define TEST_OBJ_ID 0xFFFF
#define TEST_OBJ_INST_ID 0

#define TEST_RES_S8 0

#define TEST_OBJ_RES_MAX_ID 2

static struct lwm2m_engine_obj test_obj;

static struct lwm2m_engine_obj_field test_fields[] = {
	OBJ_FIELD_DATA(TEST_RES_S8, RW, S8),
};

static struct lwm2m_engine_obj_inst test_inst;
static struct lwm2m_engine_res test_res[TEST_OBJ_RES_MAX_ID];
static struct lwm2m_engine_res_inst test_res_inst[TEST_OBJ_RES_MAX_ID];

static int8_t test_s8;

static struct lwm2m_engine_obj_inst *test_obj_create(uint16_t obj_inst_id)
{
	int i = 0, j = 0;

	init_res_instance(test_res_inst, ARRAY_SIZE(test_res_inst));

	INIT_OBJ_RES_DATA(TEST_RES_S8, test_res, i, test_res_inst, j,
			  &test_s8, sizeof(test_s8));

	test_inst.resources = test_res;
	test_inst.resource_count = i;

	return &test_inst;
}

static void test_obj_init(void)
{
	struct lwm2m_engine_obj_inst *obj_inst = NULL;

	test_obj.obj_id = TEST_OBJ_ID;
	test_obj.version_major = 1;
	test_obj.version_minor = 1;
	test_obj.is_core = false;
	test_obj.fields = test_fields;
	test_obj.field_count = ARRAY_SIZE(test_fields);
	test_obj.max_instance_count = 1U;
	test_obj.create_cb = test_obj_create;

	(void)lwm2m_register_obj(&test_obj);
	(void)lwm2m_create_obj_inst(TEST_OBJ_ID, TEST_OBJ_INST_ID, &obj_inst);
}

static void test_attr_init(void)
{
	struct lwm2m_attr *attr;

	attr = lwm2m_engine_get_next_attr(NULL, NULL);
	attr->type = LWM2M_ATTR_PMIN;
	attr->int_val = TEST_PMIN;
	attr->ref = &test_inst;

	attr = lwm2m_engine_get_next_attr(NULL, NULL);
	attr->type = LWM2M_ATTR_PMAX;
	attr->int_val = TEST_PMAX;
	attr->ref = &test_res;
}

static struct lwm2m_output_context test_out;
static struct lwm2m_obj_path test_path;
static struct coap_packet test_packet;
static uint8_t test_payload[128];
static struct link_format_out_formatter_data test_formatter_data;

static void context_reset(void)
{
	memset(&test_out, 0, sizeof(test_out));
	test_out.writer = &link_format_writer;
	test_out.out_cpkt = &test_packet;
	test_out.user_data = &test_formatter_data;

	memset(&test_payload, 0, sizeof(test_payload));
	memset(&test_packet, 0, sizeof(test_packet));
	test_packet.data = test_payload;
	test_packet.max_len = sizeof(test_payload);

	memset(&test_path, 0, sizeof(test_path));
	test_path.level = LWM2M_PATH_LEVEL_OBJECT;
	test_path.obj_id = TEST_OBJ_ID;
	test_path.obj_inst_id = TEST_OBJ_INST_ID;
	test_path.res_id = TEST_RES_S8;

	memset(&test_formatter_data, 0, sizeof(test_formatter_data));
	test_formatter_data.is_first = true;
	test_formatter_data.request_level = LWM2M_PATH_LEVEL_OBJECT;
}

static void test_prepare(void *dummy)
{
	context_reset();
}

static void test_prepare_nomem(void *dummy)
{
	context_reset();

	test_packet.offset = sizeof(test_payload);
}

ZTEST(net_content_link_format, test_put_begin_discovery)
{
	int ret;
	const char *expected_payload = "";

	test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY;

	ret = link_format_writer.put_begin(&test_out, &test_path);
	zassert_equal(ret, strlen(expected_payload),
		      "Invalid length returned");
	zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
			  strlen(expected_payload), "Invalid payload format");
	zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
			"Invalid packet offset");
}

ZTEST(net_content_link_format, test_put_begin_bs_discovery)
{
	int ret;
	const char *expected_payload = "lwm2m=\"1.0\"";

	test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;

	ret = link_format_writer.put_begin(&test_out, &test_path);
	zassert_equal(ret, strlen(expected_payload),
		      "Invalid length returned");
	zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
			  strlen(expected_payload), "Invalid payload format");
	zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
			"Invalid packet offset");
}

ZTEST(net_content_link_format, test_put_begin_register)
{
	int ret;
	const char *expected_payload = "</>;ct=11543";

	test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;

	ret = link_format_writer.put_begin(&test_out, &test_path);
	zassert_equal(ret, strlen(expected_payload),
		      "Invalid length returned");
	zassert_mem_equal(test_out.out_cpkt->data, expected_payload,
			  strlen(expected_payload), "Invalid payload format");
	zassert_equal(test_out.out_cpkt->offset, strlen(expected_payload),
			"Invalid packet offset");
}

ZTEST(net_content_link_format_nomem, test_put_begin_nomem)
{
	int ret;

	test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;

	ret = link_format_writer.put_begin(&test_out, &test_path);
	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
}

struct test_case_corelink {
	uint8_t request_level;
	uint8_t path_level;
	const char *expected_payload;
};

ZTEST(net_content_link_format, test_put_corelink_discovery)
{
	int ret;
	int i;
	struct test_case_corelink test_case[] = {
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT,
			.path_level = LWM2M_PATH_LEVEL_OBJECT,
			.expected_payload = "</65535>;ver=1.1"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT,
			.path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.expected_payload = "</65535/0>"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT,
			.path_level = LWM2M_PATH_LEVEL_RESOURCE,
			.expected_payload = "</65535/0/0>"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.expected_payload = "</65535/0>;pmin=" STRINGIFY(TEST_PMIN)
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.path_level = LWM2M_PATH_LEVEL_RESOURCE,
			.expected_payload = "</65535/0/0>;pmax=" STRINGIFY(TEST_PMAX)
		},
		{
			.request_level = LWM2M_PATH_LEVEL_RESOURCE,
			.path_level = LWM2M_PATH_LEVEL_RESOURCE,
			.expected_payload = "</65535/0/0>;pmin=" STRINGIFY(TEST_PMIN)
					    ";pmax=" STRINGIFY(TEST_PMAX)
		},
	};

	for (i = 0; i < ARRAY_SIZE(test_case); i++) {
		context_reset();

		test_formatter_data.mode = LINK_FORMAT_MODE_DISCOVERY;
		test_formatter_data.request_level = test_case[i].request_level;
		test_path.level = test_case[i].path_level;

		ret = link_format_writer.put_corelink(&test_out, &test_path);
		zassert_equal(ret, strlen(test_case[i].expected_payload),
			      "Invalid length returned");
		zassert_mem_equal(test_out.out_cpkt->data,
				  test_case[i].expected_payload,
				  strlen(test_case[i].expected_payload),
				  "Invalid payload format");
		zassert_equal(test_out.out_cpkt->offset,
			      strlen(test_case[i].expected_payload),
			      "Invalid packet offset");
	}
}

ZTEST(net_content_link_format, test_put_corelink_bs_discovery)
{
	int ret;
	int i;
	struct test_case_corelink test_case[] = {
		{
			.request_level = LWM2M_PATH_LEVEL_NONE,
			.path_level = LWM2M_PATH_LEVEL_OBJECT,
			.expected_payload = "</65535>;ver=1.1"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_NONE,
			.path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.expected_payload = "</65535/0>"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT,
			.path_level = LWM2M_PATH_LEVEL_OBJECT,
			.expected_payload = "</65535>;ver=1.1"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_OBJECT,
			.path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.expected_payload = "</65535/0>"
		},
	};

	for (i = 0; i < ARRAY_SIZE(test_case); i++) {
		context_reset();

		test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;
		test_formatter_data.request_level = test_case[i].request_level;
		test_path.level = test_case[i].path_level;

		ret = link_format_writer.put_corelink(&test_out, &test_path);
		zassert_equal(ret, strlen(test_case[i].expected_payload),
			      "Invalid length returned");
		zassert_mem_equal(test_out.out_cpkt->data,
				  test_case[i].expected_payload,
				  strlen(test_case[i].expected_payload),
				  "Invalid payload format");
		zassert_equal(test_out.out_cpkt->offset,
			      strlen(test_case[i].expected_payload),
			      "Invalid packet offset");
	}
}

ZTEST(net_content_link_format, test_put_corelink_bs_discovery_ssid)
{
	int ret;
	int i;
	char * const expected_payload[] = {
		"</0/0>;ssid=" STRINGIFY(TEST_SSID),
		"</1/0>;ssid=" STRINGIFY(TEST_SSID),
	};
	uint16_t test_obj_id[] = {
		LWM2M_OBJECT_SECURITY_ID,
		LWM2M_OBJECT_SERVER_ID,
	};

	for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
		context_reset();

		test_formatter_data.mode = LINK_FORMAT_MODE_BOOTSTRAP_DISCOVERY;
		test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE;
		test_path.level = LWM2M_PATH_LEVEL_OBJECT_INST;
		test_path.obj_id = test_obj_id[i];
		test_path.obj_inst_id = 0;

		ret = link_format_writer.put_corelink(&test_out, &test_path);
		zassert_equal(ret, strlen(expected_payload[i]),
			      "Invalid length returned");
		zassert_mem_equal(test_out.out_cpkt->data,
				  expected_payload[i],
				  strlen(expected_payload[i]),
				  "Invalid payload format");
		zassert_equal(test_out.out_cpkt->offset,
			      strlen(expected_payload[i]),
			      "Invalid packet offset");
	}
}

ZTEST(net_content_link_format, test_put_corelink_register)
{
	int ret;
	int i;
	struct test_case_corelink test_case[] = {
		{
			.request_level = LWM2M_PATH_LEVEL_NONE,
			.path_level = LWM2M_PATH_LEVEL_OBJECT,
			.expected_payload = "</65535>;ver=1.1"
		},
		{
			.request_level = LWM2M_PATH_LEVEL_NONE,
			.path_level = LWM2M_PATH_LEVEL_OBJECT_INST,
			.expected_payload = "</65535/0>"
		},
	};

	for (i = 0; i < ARRAY_SIZE(test_case); i++) {
		context_reset();

		test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
		test_formatter_data.request_level = test_case[i].request_level;
		test_path.level = test_case[i].path_level;

		ret = link_format_writer.put_corelink(&test_out, &test_path);
		zassert_equal(ret, strlen(test_case[i].expected_payload),
			      "Invalid length returned");
		zassert_mem_equal(test_out.out_cpkt->data,
				  test_case[i].expected_payload,
				  strlen(test_case[i].expected_payload),
				  "Invalid payload format");
		zassert_equal(test_out.out_cpkt->offset,
			      strlen(test_case[i].expected_payload),
			      "Invalid packet offset");
	}
}

ZTEST(net_content_link_format_nomem, test_put_corelink_nomem)
{
	int ret;

	test_formatter_data.mode = LINK_FORMAT_MODE_REGISTER;
	test_formatter_data.request_level = LWM2M_PATH_LEVEL_NONE;

	ret = link_format_writer.put_corelink(&test_out, &test_path);
	zassert_equal(ret, -ENOMEM, "Invalid error code returned");
}

static void *obj_attr_init(void)
{
	test_obj_init();
	test_attr_init();
	lwm2m_set_u16(&LWM2M_OBJ(0, 0, 10), TEST_SSID);
	lwm2m_set_u16(&LWM2M_OBJ(1, 0, 0), TEST_SSID);
	return NULL;
}

ZTEST_SUITE(net_content_link_format, NULL, obj_attr_init, test_prepare, NULL, NULL);
ZTEST_SUITE(net_content_link_format_nomem, NULL, obj_attr_init, test_prepare_nomem, NULL, NULL);
