/*
 * 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 "settings.h"
#include "net.h"
#include "rpl.h"

#define EMPTY_ENTRIES_CNT (CONFIG_BT_MESH_CRPL - ARRAY_SIZE(test_vector))

/* Used for cleaning RPL without checking it. */
static bool skip_delete;

/* Test function that should call bt_mesh_rpl_check(). */
static enum {
	SETTINGS_SAVE_ONE = 1,
	SETTINGS_DELETE
} settings_func;
/* Number of `settings_func` calls before calling bt_mesh_rpl_check() (1 means first call). */
static int settings_func_cnt;
/* Received message context. */
static struct bt_mesh_net_rx recv_msg;

/* We will change test vector during the test as it is convenient to do so. Therefore, we need
 * to keep default values separately.
 */
static const struct test_rpl_entry {
	char *name;
	uint16_t src;
	bool old_iv;
	uint32_t seq;
} test_vector_default[] = {
	{ .name = "bt/mesh/RPL/1",  .src = 0x1,  .old_iv = false, .seq = 10, },
	{ .name = "bt/mesh/RPL/17", .src = 0x17, .old_iv = true,  .seq = 32, },
	{ .name = "bt/mesh/RPL/7c", .src = 0x7c, .old_iv = false, .seq = 20, },
	{ .name = "bt/mesh/RPL/2c", .src = 0x2c, .old_iv = true,  .seq = 5,  },
	{ .name = "bt/mesh/RPL/5a", .src = 0x5a, .old_iv = true,  .seq = 12, },
};
static struct test_rpl_entry test_vector[ARRAY_SIZE(test_vector_default)];

/**** Helper functions ****/

static void prepare_rpl_and_start_reset(void)
{
	/* Add test vector to RPL. */
	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
		struct bt_mesh_net_rx msg = {
			.local_match = true,
			.ctx.addr = test_vector[i].src,
			.old_iv = test_vector[i].old_iv,
			.seq = test_vector[i].seq,
		};

		ztest_expect_value(bt_mesh_settings_store_schedule, flag,
				   BT_MESH_SETTINGS_RPL_PENDING);
		zassert_false(bt_mesh_rpl_check(&msg, NULL));
	}

	/* settings_save_one() will be triggered for all new entries when
	 * bt_mesh_rpl_pending_store() is called.
	 */
	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
		ztest_expect_data(settings_save_one, name, test_vector[i].name);
	}
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	/* Check that all added entries are in RPL. */
	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
		struct bt_mesh_net_rx msg = {
			.local_match = true,
			.ctx.addr = test_vector[i].src,
			.old_iv = test_vector[i].old_iv,
			.seq = test_vector[i].seq,
		};

		zassert_true(bt_mesh_rpl_check(&msg, NULL));
	}

	/* Simulate IVI Update. This should only flip flags. The actual storing will happen
	 * when bt_mesh_rpl_pending_store() is called.
	 */
	ztest_expect_value(bt_mesh_settings_store_schedule, flag, BT_MESH_SETTINGS_RPL_PENDING);
	bt_mesh_rpl_reset();
}

/* Should be called after the reset operation is finished. */
static void check_entries_from_test_vector(void)
{
	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
		struct bt_mesh_net_rx msg = {
			.local_match = true,
			.ctx.addr = test_vector[i].src,
			/* Entries with old_iv == true should have been deleted. old_iv in entries
			 * is flipped, so to check this we can try to add the removed entries
			 * again. RPL should accept them.
			 */
			.old_iv = !test_vector[i].old_iv,
			.seq = test_vector[i].seq
		};

		/* Removed entries can now be added again. */
		if (test_vector[i].old_iv) {
			ztest_expect_value(bt_mesh_settings_store_schedule, flag,
					   BT_MESH_SETTINGS_RPL_PENDING);
			zassert_false(bt_mesh_rpl_check(&msg, NULL));
		} else {
			zassert_true(bt_mesh_rpl_check(&msg, NULL));
		}
	}
}

static void check_empty_entries(int cnt)
{
	/* Check that RPL has the specified amount of empty entries. */
	for (int i = 0; i < cnt; i++) {
		struct bt_mesh_net_rx msg = {
			.local_match = true,
			.ctx.addr = 0x7fff - i,
			.old_iv = false,
			.seq = i,
		};

		ztest_expect_value(bt_mesh_settings_store_schedule, flag,
				   BT_MESH_SETTINGS_RPL_PENDING);
		zassert_false(bt_mesh_rpl_check(&msg, NULL));
	}

	/* Check that there are no more empty entries in RPL. */
	struct bt_mesh_net_rx msg = {
		.local_match = true,
		.ctx.addr = 0x1024,
		.old_iv = false,
		.seq = 1024,
	};
	zassert_true(bt_mesh_rpl_check(&msg, NULL));
}

static void check_op(int op)
{
	if (settings_func == op) {
		if (settings_func_cnt > 1) {
			settings_func_cnt--;
		} else {
			ztest_expect_value(bt_mesh_settings_store_schedule, flag,
					   BT_MESH_SETTINGS_RPL_PENDING);
			zassert_false(bt_mesh_rpl_check(&recv_msg, NULL));

			settings_func_cnt--;
			settings_func = 0;
		}
	}
}

static void call_rpl_check_on(int func, int cnt, struct test_rpl_entry *entry)
{
	settings_func = func;
	settings_func_cnt = cnt;

	recv_msg.local_match = true;
	recv_msg.ctx.addr = entry->src;
	recv_msg.seq = entry->seq;
	recv_msg.old_iv = entry->old_iv;
}

static void expect_pending_store(void)
{
	/* Entries with old_iv == true should be removed, others should be stored. */
	for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
		if (test_vector[i].old_iv) {
			ztest_expect_value(settings_delete, name, test_vector[i].name);
		} else {
			ztest_expect_data(settings_save_one, name, test_vector[i].name);
		}
	}
}

static bool is_rpl_check_called(void)
{
	return settings_func_cnt == 0;
}

static void verify_rpl(void)
{
	check_entries_from_test_vector();
	check_empty_entries(EMPTY_ENTRIES_CNT);
}

static void setup(void *f)
{
	/* Restore test vector. */
	memcpy(test_vector, test_vector_default, sizeof(test_vector));

	/* Clear RPL before every test. */
	skip_delete = true;
	ztest_expect_value(bt_mesh_settings_store_schedule, flag, BT_MESH_SETTINGS_RPL_PENDING);
	bt_mesh_rpl_clear();
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	skip_delete = false;

	settings_func = 0;
	settings_func_cnt = 0;
}

/**** Mocked functions ****/

void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag)
{
	ztest_check_expected_value(flag);
}

void bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag)
{
}

int settings_save_one(const char *name, const void *value, size_t val_len)
{
	ztest_check_expected_data(name, strlen(name));

	check_op(SETTINGS_SAVE_ONE);

	return 0;
}

int settings_delete(const char *name)
{
	if (skip_delete) {
		return 0;
	}

	ztest_check_expected_data(name, strlen(name));

	check_op(SETTINGS_DELETE);

	return 0;
}

/**** Tests ****/

ZTEST_SUITE(bt_mesh_rpl_reset, NULL, NULL, setup, NULL, NULL);

/** Test that entries with old_iv == true are removed after the reset operation finished. */
ZTEST(bt_mesh_rpl_reset, test_reset_normal)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a valid entry that was just deleted. The entry should be
 * stored after the reset operation is finished.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_delete_same_entry)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	/* Take the first entry with old_iv == true and simulate msg reception with same src
	 * address and correct IVI after the entry was deleted.
	 */
	struct test_rpl_entry *entry = &test_vector[1];

	zassert_true(entry->old_iv);
	entry->old_iv = false;
	call_rpl_check_on(SETTINGS_DELETE, 1, entry);

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* Call bt_mesh_rpl_pending_store() to store new entry. */
	ztest_expect_data(settings_save_one, name, entry->name);
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a valid entry that was just stored. The entry should be stored
 * after the reset operation is finished.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_save_same_entry)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	/* Take the first entry with old_iv == false and simulate msg reception with same src
	 * address and correct IVI after the entry was stored.
	 */
	struct test_rpl_entry *entry = &test_vector[0];

	zassert_false(entry->old_iv);
	call_rpl_check_on(SETTINGS_SAVE_ONE, 1, entry);

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* Call bt_mesh_rpl_pending_store() to store new entry. */
	ztest_expect_data(settings_save_one, name, entry->name);
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a valid entry that has not yet been deleted. The entry should
 * be stored during the reset operation.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_delete_other_entry)
{
	prepare_rpl_and_start_reset();

	/* Take the non-first entry with old_iv == true and simulate msg reception with same src
	 * address and correct IVI before the entry is deleted.
	 *
	 * Should be done before calling ztest_expect_data() because the expectation changes.
	 */
	struct test_rpl_entry *entry = &test_vector[3];

	zassert_true(entry->old_iv);
	entry->old_iv = false;
	call_rpl_check_on(SETTINGS_DELETE, 1, entry);

	expect_pending_store();

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* The entry should have been deleted in previous bt_mesh_rpl_pending_store() call. Another
	 * call should not do anything.
	 */
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/* Test that RPL accepts and stores a valid entry that has not yet been stored. The entry should be
 * stored during the reset operation.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_save_other_entry)
{
	prepare_rpl_and_start_reset();

	/* Take RPL entry from test vector that has old_iv == false and is not stored yet after
	 * bt_mesh_reset() call and try to store it again. RPL has such entry with flipped old_iv,
	 * so this one can be accepted as is.
	 *
	 * Should be done before calling ztest_expect_data() because the expectation changes.
	 */
	struct test_rpl_entry *entry = &test_vector[2];

	zassert_false(entry->old_iv);
	call_rpl_check_on(SETTINGS_SAVE_ONE, 1, entry);

	expect_pending_store();

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* The entry should have been stored in previous bt_mesh_rpl_pending_store() call. Another
	 * call should not do anything.
	 */
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a valid entry that has been deleted during the reset operation.
 * The entry will be added at the end of RPL, therefore it should be stored during the reset
 * operation.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_delete_deleted_entry)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	/* Take the first entry with old_iv == true, wait until bt_mesh_rpl_pending_store() takes
	 * another entry after that one and simulate msg reception.
	 */
	struct test_rpl_entry *entry = &test_vector[1];

	zassert_true(entry->old_iv);
	entry->old_iv = false;
	call_rpl_check_on(SETTINGS_DELETE, 2, entry);
	/* The entry will be stored during the reset operation as it will be added to the end of
	 * the RPL.
	 */
	ztest_expect_data(settings_save_one, name, entry->name);

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* The new entry should have been stored already. Another bt_mesh_rpl_pending_store() call
	 * should not do anything.
	 */
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a valid entry that has been stored during the reset operation.
 * Since the entry has been already in the list, it should be stored again after the reset
 * operation is finished.
 */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_store_stored_entry)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	/* Take the first entry with old_iv == false, wait until bt_mesh_rpl_pending_store() takes
	 * another entry after that one and simulate msg reception.
	 */
	struct test_rpl_entry *entry = &test_vector[0];

	zassert_false(entry->old_iv);
	entry->old_iv = true;
	entry->seq++;
	call_rpl_check_on(SETTINGS_SAVE_ONE, 2, entry);

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* The entry was updated after bt_mesh_rpl_pending_store() checked it. So it should be
	 * stored again.
	 */
	ztest_expect_data(settings_save_one, name, entry->name);
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	verify_rpl();
}

/** Test that RPL accepts and stores a new entry when the reset operation is not yet finished. */
ZTEST(bt_mesh_rpl_reset, test_rpl_check_on_save_new_entry)
{
	prepare_rpl_and_start_reset();
	expect_pending_store();

	/* Add a new entry to RPL during the reset operation. */
	struct test_rpl_entry entry = {
		.name = "bt/mesh/RPL/2b",
		.src = 43,
		.old_iv = false,
		.seq = 32,
	};
	ztest_expect_data(settings_save_one, name, entry.name);
	call_rpl_check_on(SETTINGS_SAVE_ONE, 1, &entry);

	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);
	zassert_true(is_rpl_check_called());

	/* The entry should have been stored in previous bt_mesh_rpl_pending_store() call. Another
	 * call should not do anything.
	 */
	bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES);

	check_entries_from_test_vector();
	/* Check that added entry in the RPL. */
	struct bt_mesh_net_rx msg = {
		.local_match = true,
		.ctx.addr = entry.src,
		.old_iv = entry.old_iv,
		.seq = entry.seq
	};
	zassert_true(bt_mesh_rpl_check(&msg, NULL));
	check_empty_entries(EMPTY_ENTRIES_CNT - 1);
}
