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

#include <zephyr/fff.h>
#include <zephyr/logging/log.h>
#include <zephyr/ztest.h>
#include <zephyr/net/socket.h>

#include "lwm2m_engine.h"
#include "lwm2m_rd_client.h"

#include "stubs.h"
#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME)
#include "timer_model.h"
#endif

#define LOG_LEVEL	LOG_LEVEL_DBG
LOG_MODULE_REGISTER(lwm2m_engine_test);

DEFINE_FFF_GLOBALS;
#define FFF_FAKES_LIST(FAKE)

static uint8_t my_buf[256];
static uint16_t my_data_len = 1;
static struct lwm2m_message my_msg;
static struct lwm2m_engine_obj_field my_obj_field;

static int lwm2m_get_res_buf_custom_fake(const struct lwm2m_obj_path *path, void **buffer_ptr,
					 uint16_t *buffer_len, uint16_t *data_len,
					 uint8_t *data_flags)
{
	if (buffer_ptr)
		*buffer_ptr = my_buf;
	if (buffer_len)
		*buffer_len = sizeof(my_buf);
	if (data_len)
		*data_len = my_data_len;

	return 0;
}

static struct lwm2m_message *find_msg_custom_fake(struct coap_pending *pending,
						  struct coap_reply *reply)
{
	return &my_msg;
}

static struct lwm2m_engine_obj_field *
lwm2m_get_engine_obj_field_custom_fake(struct lwm2m_engine_obj *obj, int res_id)
{
	return &my_obj_field;
}

static int lwm2m_get_bool_custom_fake(const struct lwm2m_obj_path *path, bool *value)
{
	*value = false;

	return 0;
}

static void test_service(struct k_work *work)
{
	k_sleep(K_MSEC(10));
}

static void setup(void *data)
{
#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME)
	/* It is enough that some slow-down is happening on sleeps, it does not have to be
	 * real time
	 */
	hwtimer_set_rt_ratio(100.0);
#endif
	/* Register resets */
	DO_FOREACH_FAKE(RESET_FAKE);

	/* reset common FFF internal structures */
	FFF_RESET_HISTORY();

	clear_socket_events();
	lwm2m_get_res_buf_fake.custom_fake = lwm2m_get_res_buf_custom_fake;
	find_msg_fake.custom_fake = find_msg_custom_fake;
	lwm2m_get_engine_obj_field_fake.custom_fake = lwm2m_get_engine_obj_field_custom_fake;
	lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_custom_fake;
}

ZTEST_SUITE(lwm2m_engine, NULL, NULL, setup, NULL, NULL);

ZTEST(lwm2m_engine, test_start_stop)
{
	int ret;
	struct lwm2m_ctx ctx;
	char host_name[10] = "my_host";

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.remote_addr.sa_family = AF_INET;
	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.desthostname = host_name;
	ctx.desthostnamelen = strlen(host_name);
	ctx.hostname_verify = true;
	ctx.use_dtls = true;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);

	struct lwm2m_ctx **eng_ctx = lwm2m_sock_ctx();
	int nfds = lwm2m_sock_nfds();

	zassert_not_null(eng_ctx);
	zassert_true(nfds > 0);
	zassert_equal(eng_ctx[0], &ctx);

	/* wait for socket receive thread */
	k_sleep(K_MSEC(1000));
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
}

ZTEST(lwm2m_engine, test_pause_resume)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.remote_addr.sa_family = AF_INET;
	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	ret = lwm2m_engine_resume();
	zassert_equal(ret, -EPERM);
	ret = lwm2m_engine_pause();
	zassert_equal(ret, 0);
	ret = lwm2m_engine_pause();
	zassert_equal(ret, 0);
	ret = lwm2m_engine_resume();
	zassert_equal(ret, 0);
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
}

ZTEST(lwm2m_engine, test_engine_add_service)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.remote_addr.sa_family = AF_INET;
	ctx.load_credentials = NULL;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	ret = lwm2m_engine_add_service(test_service, 1000);
	zassert_equal(ret, 0);
	/* wait for socket receive thread */
	k_sleep(K_MSEC(1500));
	ret = lwm2m_engine_update_service_period(test_service, 500);
	zassert_equal(ret, 0);
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
}

ZTEST(lwm2m_engine, test_no_sa_family)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, -EPROTONOSUPPORT);
	lwm2m_engine_stop(&ctx);
}

ZTEST(lwm2m_engine, test_connect_fail)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.remote_addr.sa_family = AF_INET;

	errno = ENETDOWN;
	z_impl_zsock_connect_fake.return_val = -1;
	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, -ENETDOWN);
	lwm2m_engine_stop(&ctx);
}

ZTEST(lwm2m_engine, test_socket_suspend_resume_connection)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.remote_addr.sa_family = AF_INET;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	ret = lwm2m_socket_suspend(&ctx);
	zassert_equal(ret, 0);
	zassert_equal(ctx.connection_suspended, true);
	ret = lwm2m_engine_connection_resume(&ctx);
	zassert_equal(ret, 0);
	zassert_equal(ctx.connection_suspended, false);
	lwm2m_engine_stop(&ctx);
}

ZTEST(lwm2m_engine, test_check_notifications)
{
	int ret;
	struct lwm2m_ctx ctx;
	struct observe_node obs;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.remote_addr.sa_family = AF_INET;
	sys_slist_init(&ctx.observer);

	obs.last_timestamp = k_uptime_get();
	obs.event_timestamp = k_uptime_get() + 1000U;
	obs.resource_update = false;
	obs.active_notify = NULL;

	sys_slist_append(&ctx.observer, &obs.node);

	lwm2m_rd_client_is_registred_fake.return_val = true;
	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	/* wait for socket receive thread */
	k_sleep(K_MSEC(2000));
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
	zassert_equal(generate_notify_message_fake.call_count, 1, "Notify message not generated");
	zassert_equal(engine_observe_shedule_next_event_fake.call_count, 1,
		      "Next observe event not scheduled");
}

ZTEST(lwm2m_engine, test_push_queued_buffers)
{
	int ret;
	struct lwm2m_ctx ctx;
	struct lwm2m_message msg;
	struct coap_pending pending;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	sys_slist_init(&ctx.queued_messages);
	msg.ctx = &ctx;
	msg.pending = &pending;
	sys_slist_append(&ctx.queued_messages, &msg.node);
	ret = lwm2m_push_queued_buffers(&ctx);
	zassert_equal(ret, 0);
}

ZTEST(lwm2m_engine, test_validate_write_access)
{
	int ret;
	struct lwm2m_ctx ctx;
	struct lwm2m_message msg;
	struct lwm2m_engine_res resources;
	struct lwm2m_engine_obj_inst obj_inst;
	struct lwm2m_engine_obj_field *obj_field = NULL;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.bootstrap_mode = true;
	msg.ctx = &ctx;
	msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0);
	obj_inst.resources = &resources;
	obj_inst.resource_count = 1U;
	ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
	zassert_equal(ret, 0);

	obj_inst.resource_count = 0U;
	ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
	zassert_equal(ret, -EINVAL);

	msg.path = LWM2M_OBJ(LWM2M_OBJECT_DEVICE_ID, 0);
	ret = lwm2m_engine_validate_write_access(&msg, &obj_inst, &obj_field);
	zassert_equal(ret, -EPERM);
}

ZTEST(lwm2m_engine, test_bootstrap_delete)
{
	int ret;
	struct lwm2m_message msg;

	msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0);
	ret = bootstrap_delete(&msg);
	zassert_equal(ret, -EPERM);

	msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 1);
	ret = bootstrap_delete(&msg);
	zassert_equal(ret, 0);
	zassert_equal(0, lwm2m_delete_obj_inst_fake.arg0_history[0]);
	zassert_equal(1, lwm2m_delete_obj_inst_fake.arg1_history[0]);


	struct lwm2m_engine_obj sec_obj = {.obj_id = 0};
	struct lwm2m_engine_obj_inst sec_inst = {
		.obj_inst_id = 2,
		.obj = &sec_obj
	};
	sys_slist_append(lwm2m_engine_obj_inst_list(), &sec_inst.node);

	msg.path = LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID);
	ret = bootstrap_delete(&msg);
	zassert_equal(ret, 0);
	zassert_equal(0, lwm2m_delete_obj_inst_fake.arg0_history[1]);
	zassert_equal(2, lwm2m_delete_obj_inst_fake.arg1_history[1]);

	msg.path = LWM2M_OBJ(LWM2M_OBJECT_DEVICE_ID, 0);
	ret = bootstrap_delete(&msg);
	zassert_equal(ret, -EPERM);
}

ZTEST(lwm2m_engine, test_retransmit_request)
{
	int ret;
	struct lwm2m_ctx ctx;
	struct coap_pending pending_1;
	struct coap_pending pending_2;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.remote_addr.sa_family = AF_INET;

	pending_1.t0 = k_uptime_get();
	pending_1.timeout = 200U;
	pending_1.retries = 0;
	ctx.pendings[0] = pending_1;

	pending_2.t0 = k_uptime_get();
	pending_2.timeout = 200U;
	pending_2.retries = 1;
	ctx.pendings[1] = pending_2;

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	/* wait for socket receive thread */
	k_sleep(K_MSEC(500));
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
	zassert_not_equal(lwm2m_reset_message_fake.call_count, 0, "Message was not reseted");
	zassert_not_equal(lwm2m_send_message_async_fake.call_count, 0, "Message was not sent");
}

ZTEST(lwm2m_engine, test_socket_recv)
{
	int ret;
	struct lwm2m_ctx ctx;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.remote_addr.sa_family = AF_INET;
	ctx.sock_fd = -1;

	set_socket_events(ZSOCK_POLLIN);

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	/* wait for socket receive thread */
	k_sleep(K_MSEC(1000));
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
	zassert_true(lwm2m_udp_receive_fake.call_count > 0);
}

ZTEST(lwm2m_engine, test_socket_send)
{
	int ret;
	struct lwm2m_ctx ctx;
	struct lwm2m_message msg;
	struct coap_pending pending;

	(void)memset(&ctx, 0x0, sizeof(ctx));

	ctx.remote_addr.sa_family = AF_INET;
	ctx.sock_fd = -1;
	sys_slist_init(&ctx.queued_messages);
	msg.ctx = &ctx;
	msg.pending = &pending;
	msg.type = COAP_TYPE_CON;
	sys_slist_append(&ctx.queued_messages, &msg.node);

	ret = lwm2m_push_queued_buffers(&ctx);
	zassert_equal(ret, 0);

	set_socket_events(ZSOCK_POLLOUT);

	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);
	/* wait for socket receive thread */
	k_sleep(K_MSEC(2000));
	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
	LOG_INF("Count %d", coap_pending_cycle_fake.call_count);
	zassert_equal(coap_pending_cycle_fake.call_count, 1, "coap_pending_cycle not called");
}

ZTEST(lwm2m_engine, test_security)
{
	struct lwm2m_ctx ctx;
	char host_name[10] = "my_host";

	(void)memset(&ctx, 0x0, sizeof(ctx));
	my_data_len = snprintk(my_buf, sizeof(my_buf), "-----BEGIN SOMETHING");

	ctx.remote_addr.sa_family = AF_INET;
	ctx.sock_fd = -1;
	ctx.load_credentials = NULL;
	ctx.desthostname = host_name;
	ctx.desthostnamelen = strlen(host_name);
	ctx.hostname_verify = true;
	ctx.use_dtls = false;

	lwm2m_security_mode_fake.return_val = LWM2M_SECURITY_NOSEC;

	zassert_equal(lwm2m_engine_start(&ctx), 0);
	zassert_equal(lwm2m_engine_stop(&ctx), 0);

	ctx.use_dtls = true;
	zassert_equal(lwm2m_engine_start(&ctx), -EINVAL);
	zassert_equal(lwm2m_engine_stop(&ctx), 0);

	RESET_FAKE(z_impl_zsock_setsockopt);
	lwm2m_security_mode_fake.return_val = LWM2M_SECURITY_PSK;
	zassert_equal(lwm2m_engine_start(&ctx), 0);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[0], TLS_SEC_TAG_LIST);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[1], TLS_HOSTNAME);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[2], TLS_PEER_VERIFY);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[3], TLS_CIPHERSUITE_LIST);
	zassert_true(tls_credential_delete_fake.call_count > 3);
	zassert_true(tls_credential_add_fake.call_count == 2);
	zassert_equal(tls_credential_add_fake.arg1_history[0], TLS_CREDENTIAL_PSK_ID);
	zassert_equal(tls_credential_add_fake.arg1_history[1], TLS_CREDENTIAL_PSK);
	zassert_equal(lwm2m_engine_stop(&ctx), 0);

	RESET_FAKE(z_impl_zsock_setsockopt);
	RESET_FAKE(tls_credential_add);
	lwm2m_security_mode_fake.return_val = LWM2M_SECURITY_CERT;
	ctx.hostname_verify = false;
	zassert_equal(lwm2m_engine_start(&ctx), 0);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[0], TLS_SEC_TAG_LIST);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[1], TLS_PEER_VERIFY);
	zassert_equal(z_impl_zsock_setsockopt_fake.arg2_history[2], TLS_CIPHERSUITE_LIST);
	zassert_true(tls_credential_add_fake.call_count == 3);
	zassert_equal(tls_credential_add_fake.arg1_history[0], TLS_CREDENTIAL_SERVER_CERTIFICATE);
	zassert_equal(tls_credential_add_fake.arg1_history[1], TLS_CREDENTIAL_PRIVATE_KEY);
	zassert_equal(tls_credential_add_fake.arg1_history[2], TLS_CREDENTIAL_CA_CERTIFICATE);
	zassert_equal(lwm2m_engine_stop(&ctx), 0);
}

static enum lwm2m_socket_states last_state;

static void socket_state(int fd, enum lwm2m_socket_states state)
{
	(void) fd;
	last_state = state;
}

ZTEST(lwm2m_engine, test_socket_state)
{
	int ret;
	struct lwm2m_ctx ctx = {
		.remote_addr.sa_family = AF_INET,
		.sock_fd = -1,
		.set_socket_state = socket_state,
	};
	struct lwm2m_message msg1 = {
		.ctx = &ctx,
		.type = COAP_TYPE_CON,
	};
	struct lwm2m_message msg2 = msg1;
	struct lwm2m_message ack = {
		.ctx = &ctx,
		.type = COAP_TYPE_ACK,
	};

	sys_slist_init(&ctx.pending_sends);
	ret = lwm2m_engine_start(&ctx);
	zassert_equal(ret, 0);

	/* One confimable in queue, should cause ONE_RESPONSE status */
	coap_pendings_count_fake.return_val = 1;
	sys_slist_append(&ctx.pending_sends, &msg1.node);
	set_socket_events(ZSOCK_POLLOUT);
	k_sleep(K_MSEC(100));
	zassert_equal(last_state, LWM2M_SOCKET_STATE_ONE_RESPONSE);

	/* More than one messages in queue, not empty, should cause ONGOING */
	coap_pendings_count_fake.return_val = 2;
	sys_slist_append(&ctx.pending_sends, &msg1.node);
	sys_slist_append(&ctx.pending_sends, &msg2.node);
	set_socket_events(ZSOCK_POLLOUT);
	k_sleep(K_MSEC(100));
	zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING);

	/* Last out, while waiting for ACK to both, should still cause ONGOING */
	coap_pendings_count_fake.return_val = 2;
	set_socket_events(ZSOCK_POLLOUT);
	k_sleep(K_MSEC(100));
	zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING);

	/* Only one Ack transmiting, nothing expected back -> LAST */
	coap_pendings_count_fake.return_val = 0;
	sys_slist_append(&ctx.pending_sends, &ack.node);
	set_socket_events(ZSOCK_POLLOUT);
	k_sleep(K_MSEC(100));
	zassert_equal(last_state, LWM2M_SOCKET_STATE_LAST);

	/* Socket suspended (as in QUEUE_RX_OFF), should cause NO_DATA */
	ret = lwm2m_socket_suspend(&ctx);
	zassert_equal(ret, 0);
	zassert_equal(last_state, LWM2M_SOCKET_STATE_NO_DATA);

	ret = lwm2m_engine_stop(&ctx);
	zassert_equal(ret, 0);
}
