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

#include <zephyr/ztest.h>
#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/mesh.h>
#include <zephyr/random/random.h>

#include "net.h"
#include "access.h"
#include "delayable_msg.h"

#define SRC_ADDR 0x0002
#define RX_ADDR  0xc000

static void start_cb(uint16_t duration, int err, void *cb_data);

struct bt_mesh_net bt_mesh;

static struct bt_mesh_msg_ctx gctx = {.net_idx = 0,
				      .app_idx = 0,
				      .addr = 0,
				      .recv_dst = RX_ADDR,
				      .uuid = NULL,
				      .recv_rssi = 0,
				      .recv_ttl = 0x05,
				      .send_rel = false,
				      .rnd_delay = true,
				      .send_ttl = 0x06};

static struct bt_mesh_send_cb send_cb = {
	.start = start_cb,
};

static bool is_fake_random;
static bool check_expectations;
static bool accum_mask;
static bool do_not_call_cb;
static uint16_t fake_random;
static uint8_t *buf_data;
static size_t buf_data_size;
static uint16_t id_mask;
static int cb_err_status;

K_SEM_DEFINE(delayed_msg_sent, 0, 1);

/**** Mocked functions ****/
int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr,
			const struct bt_mesh_send_cb *cb, void *cb_data)
{
	if (check_expectations) {
		gctx.rnd_delay = false;
		ztest_check_expected_data(ctx, sizeof(struct bt_mesh_msg_ctx));
		gctx.rnd_delay = true;
		ztest_check_expected_value(src_addr);
		ztest_check_expected_data(cb, sizeof(struct bt_mesh_send_cb));
		ztest_check_expected_data(cb_data, sizeof(uint32_t));
		zexpect_mem_equal(buf->data, buf_data, buf_data_size, "Buffer data corrupted");
	}

	if (cb && !do_not_call_cb) {
		cb->start(0x0, cb_err_status, cb_data);
	}

	return cb_err_status;
}

int bt_rand(void *buf, size_t len)
{
	if (is_fake_random) {
		*(uint16_t *)buf = fake_random;
	} else {
		sys_rand_get(buf, len);
	}
	return 0;
}
/**** Mocked functions ****/

static void start_cb(uint16_t duration, int err, void *cb_data)
{

	zassert_equal(err, cb_err_status, "err: %d, cb_err_status: %d", err, cb_err_status);

	if (accum_mask) {
		id_mask |= 1 << *(uint16_t *)cb_data;
	} else {
		k_sem_give(&delayed_msg_sent);
	}
}

static void set_expectation(struct net_buf_simple *buf, uint32_t *buf_id)
{
	ztest_expect_data(bt_mesh_access_send, ctx, &gctx);
	ztest_expect_value(bt_mesh_access_send, src_addr, SRC_ADDR);
	ztest_expect_data(bt_mesh_access_send, cb, &send_cb);
	ztest_expect_data(bt_mesh_access_send, cb_data, buf_id);
	buf_data = buf->__buf;
	buf_data_size = buf->size;
	check_expectations = true;
}

static void tc_setup(void *fixture)
{
	is_fake_random = false;
	check_expectations = false;
	accum_mask = false;
	id_mask = 0;
	do_not_call_cb = false;
	cb_err_status = 0;
	k_sem_reset(&delayed_msg_sent);
	bt_mesh_delayable_msg_init();
}

static void tc_teardown(void *fixture)
{
	zassert_equal(gctx.net_idx, 0);
	zassert_equal(gctx.app_idx, 0);
	zassert_equal(gctx.addr, 0);
	zassert_equal(gctx.recv_dst, RX_ADDR);
	zassert_is_null(gctx.uuid);
	zassert_equal(gctx.recv_rssi, 0);
	zassert_equal(gctx.recv_ttl, 0x05);
	zassert_false(gctx.send_rel);
	zassert_true(gctx.rnd_delay);
	zassert_equal(gctx.send_ttl, 0x06);
}

ZTEST_SUITE(bt_mesh_delayable_msg, NULL, NULL, tc_setup, tc_teardown, NULL);

/* Simple single message sending with full size.
 */
ZTEST(bt_mesh_delayable_msg, test_single_sending)
{
	uint32_t buf_id = 0x55aa55aa;
	uint8_t *payload;

	NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);

	payload = net_buf_simple_add(&buf, BT_MESH_TX_SDU_MAX);
	for (int i = 0; i < BT_MESH_TX_SDU_MAX; i++) {
		payload[i] = i;
	}

	set_expectation(&buf, &buf_id);
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id));

	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been sent.");
}

/* The test checks that the delayed message mechanism sorts
 * the incoming messages according to the transmission start timestamp.
 */
ZTEST(bt_mesh_delayable_msg, test_self_sorting)
{
	uint8_t tx_data[20];
	uint32_t buf1_id = 1;
	uint32_t buf2_id = 2;
	uint32_t buf3_id = 3;
	uint32_t buf4_id = 4;

	NET_BUF_SIMPLE_DEFINE(buf1, 20);
	NET_BUF_SIMPLE_DEFINE(buf2, 20);
	NET_BUF_SIMPLE_DEFINE(buf3, 20);
	NET_BUF_SIMPLE_DEFINE(buf4, 20);

	memset(tx_data, 1, 20);
	memcpy(net_buf_simple_add(&buf1, 20), tx_data, 20);
	memset(tx_data, 2, 20);
	memcpy(net_buf_simple_add(&buf2, 20), tx_data, 20);
	memset(tx_data, 3, 20);
	memcpy(net_buf_simple_add(&buf3, 20), tx_data, 20);
	memset(tx_data, 4, 20);
	memcpy(net_buf_simple_add(&buf4, 20), tx_data, 20);

	is_fake_random = true;
	fake_random = 30;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf1, SRC_ADDR, &send_cb, &buf1_id));
	fake_random = 10;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf2, SRC_ADDR, &send_cb, &buf2_id));
	fake_random = 20;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf3, SRC_ADDR, &send_cb, &buf3_id));
	fake_random = 40;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf4, SRC_ADDR, &send_cb, &buf4_id));

	set_expectation(&buf2, &buf2_id);
	zassert_ok(k_sem_take(&delayed_msg_sent, K_MSEC(100)),
		   "Delayed message has not been sent.");
	set_expectation(&buf3, &buf3_id);
	zassert_ok(k_sem_take(&delayed_msg_sent, K_MSEC(100)),
		   "Delayed message has not been sent.");
	set_expectation(&buf1, &buf1_id);
	zassert_ok(k_sem_take(&delayed_msg_sent, K_MSEC(100)),
		   "Delayed message has not been sent.");
	set_expectation(&buf4, &buf4_id);
	zassert_ok(k_sem_take(&delayed_msg_sent, K_MSEC(100)),
		   "Delayed message has not been sent.");
}

/* The test checks that the delayed msg mechanism can allocate new context
 * if all contexts are in use by sending the message, that is the closest to
 * the tx time.
 */
ZTEST(bt_mesh_delayable_msg, test_ctx_reallocation)
{
	uint8_t tx_data[20];
	uint32_t buf_id1 = 0;
	uint32_t buf_id2 = 1;
	uint32_t buf_id3 = 2;
	uint32_t buf_id4 = 3;
	uint32_t buf_id5 = 4;

	NET_BUF_SIMPLE_DEFINE(buf, 20);

	memset(tx_data, 1, 20);
	memcpy(net_buf_simple_add(&buf, 20), tx_data, 20);

	accum_mask = true;
	is_fake_random = true;
	fake_random = 10;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id1));
	fake_random = 30;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id2));
	fake_random = 20;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id3));
	fake_random = 40;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id4));
	fake_random = 40;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id5));
	zassert_equal(id_mask, 0x0001, "Delayed message context reallocation was broken");
	k_sleep(K_MSEC(500));
	zassert_equal(id_mask, 0x001F);
}

/* The test checks that the delayed msg mechanism can allocate new chunks
 * if all chunks are in use by sending the other messages.
 */
ZTEST(bt_mesh_delayable_msg, test_chunk_reallocation)
{
	uint8_t tx_data[BT_MESH_TX_SDU_MAX];
	uint32_t buf_id1 = 0;
	uint32_t buf_id2 = 1;
	uint32_t buf_id3 = 2;
	uint32_t buf_id4 = 3;

	NET_BUF_SIMPLE_DEFINE(buf1, 20);
	NET_BUF_SIMPLE_DEFINE(buf2, BT_MESH_TX_SDU_MAX);

	memset(tx_data, 1, BT_MESH_TX_SDU_MAX);
	memcpy(net_buf_simple_add(&buf1, 20), tx_data, 20);
	memcpy(net_buf_simple_add(&buf2, BT_MESH_TX_SDU_MAX), tx_data, BT_MESH_TX_SDU_MAX);

	accum_mask = true;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf1, SRC_ADDR, &send_cb, &buf_id1));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf1, SRC_ADDR, &send_cb, &buf_id2));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf1, SRC_ADDR, &send_cb, &buf_id3));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf2, SRC_ADDR, &send_cb, &buf_id4));
	zassert_equal(id_mask, 0x0007, "Delayed message chunks reallocation was broken");
	k_sleep(K_MSEC(500));
	zassert_equal(id_mask, 0x000F);
}

/* The test checks that the delayed msg mechanism can reschedule access messages
 * transport layes doesn't have enough memory or buffers at the moment.
 * Also it checks that the delayed msg mechanism can handle the other transport
 * layer errors without rescheduling appropriate access messages.
 */
ZTEST(bt_mesh_delayable_msg, test_cb_error_status)
{
	uint32_t buf_id = 0x55aa55aa;
	uint8_t tx_data[BT_MESH_TX_SDU_MAX];

	NET_BUF_SIMPLE_DEFINE(buf1, 20);
	NET_BUF_SIMPLE_DEFINE(buf2, 20);
	NET_BUF_SIMPLE_DEFINE(buf3, 20);

	memset(tx_data, 1, BT_MESH_TX_SDU_MAX);
	memcpy(net_buf_simple_add(&buf1, 20), tx_data, 20);
	memcpy(net_buf_simple_add(&buf2, 20), tx_data, 20);
	memcpy(net_buf_simple_add(&buf3, 20), tx_data, 20);

	cb_err_status = -ENOBUFS;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf1, SRC_ADDR, &send_cb, &buf_id));
	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been handled.");
	cb_err_status = 0;
	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been sent.");

	cb_err_status = -EBUSY;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf2, SRC_ADDR, &send_cb, &buf_id));
	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been handled.");
	cb_err_status = 0;
	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been sent.");

	cb_err_status = -EINVAL;
	do_not_call_cb = true;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf3, SRC_ADDR, &send_cb, &buf_id));
	zassert_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		   "Delayed message has not been handled.");
	cb_err_status = 0;
	zexpect_not_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		       "Delayed message has not been handled.");
}

/* The test checks that the delayed msg mechanism raises
 * the model message callback with the appropriate error code after
 * stopping the functionality.
 */
ZTEST(bt_mesh_delayable_msg, test_stop_handler)
{
	uint8_t tx_data[20];
	uint32_t buf_id1 = 0;
	uint32_t buf_id2 = 1;
	uint32_t buf_id3 = 2;
	uint32_t buf_id4 = 3;

	NET_BUF_SIMPLE_DEFINE(buf, 20);

	memset(tx_data, 1, 20);
	memcpy(net_buf_simple_add(&buf, 20), tx_data, 20);

	accum_mask = true;
	cb_err_status = -ENODEV;
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id1));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id2));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id3));
	zexpect_ok(bt_mesh_delayable_msg_manage(&gctx, &buf, SRC_ADDR, &send_cb, &buf_id4));
	bt_mesh_delayable_msg_stop();
	zexpect_not_ok(k_sem_take(&delayed_msg_sent, K_SECONDS(1)),
		       "Delayed message has been sent after stopping.");
	zassert_equal(id_mask, 0x000F, "Not all scheduled messages were handled after stopping");
}
