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

#include "host_mocks/print_utils.h"
#include "mocks/keys_help_utils.h"
#include "testing_common_defs.h"

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/fff.h>
#include <zephyr/kernel.h>

#include <host/keys.h>

DEFINE_FFF_GLOBALS;

/* This LUT contains different combinations of ID, Address and key type.
 * Item in this list will be used to fill keys pool.
 */
static const struct id_addr_type testing_id_addr_type_lut[] = {
	{BT_ADDR_ID_1, BT_ADDR_LE_1, BT_KEYS_PERIPH_LTK},
	{BT_ADDR_ID_1, BT_ADDR_LE_2, BT_KEYS_IRK},
	{BT_ADDR_ID_2, BT_ADDR_LE_1, BT_KEYS_LTK},
	{BT_ADDR_ID_2, BT_ADDR_LE_2, BT_KEYS_LOCAL_CSRK},
	{BT_ADDR_ID_3, BT_ADDR_LE_1, BT_KEYS_REMOTE_CSRK},
	{BT_ADDR_ID_3, BT_ADDR_LE_2, BT_KEYS_LTK_P256},
	{BT_ADDR_ID_4, BT_ADDR_LE_1, BT_KEYS_ALL}};

/* This list will hold returned references while filling keys pool */
static struct bt_keys *returned_keys_refs[CONFIG_BT_MAX_PAIRED];

BUILD_ASSERT(ARRAY_SIZE(testing_id_addr_type_lut) == CONFIG_BT_MAX_PAIRED);
BUILD_ASSERT(ARRAY_SIZE(testing_id_addr_type_lut) == ARRAY_SIZE(returned_keys_refs));

static void *empty_list_ts_setup(void)
{
	clear_key_pool();

	return NULL;
}

ZTEST_SUITE(bt_keys_get_type_initially_empty_list, NULL, empty_list_ts_setup, NULL, NULL, NULL);

static void *full_list_ts_setup(void)
{
	clear_key_pool();
	int rv = fill_key_pool_by_id_addr_type(
		testing_id_addr_type_lut, ARRAY_SIZE(testing_id_addr_type_lut), returned_keys_refs);

	zassert_true(rv == 0, "Failed to fill keys pool list, error code %d", -rv);

	return NULL;
}

ZTEST_SUITE(bt_keys_get_type_initially_filled_list, NULL, full_list_ts_setup, NULL, NULL, NULL);

/*
 *  Test getting a non-existing key reference with type, ID and Address while the list isn't full.
 *
 *  Constraints:
 *   - Keys pool list isn't full
 *   - ID and address pair used doesn't exist in the keys pool list
 *
 *  Expected behaviour:
 *   - A key slot is reserved and data type, ID and Address are stored
 *   - A valid reference is returned by bt_keys_get_type()
 *   - ID value matches the one passed to bt_keys_get_type()
 *   - Address value matches the one passed to bt_keys_get_type()
 *   - Key type value matches the one passed to bt_keys_get_type()
 */
ZTEST(bt_keys_get_type_initially_empty_list, test_get_non_existing_key_reference)
{
	struct bt_keys *returned_key;
	int type;
	uint8_t id;
	bt_addr_le_t *addr;
	struct id_addr_type const *params_vector;

	for (size_t i = 0; i < ARRAY_SIZE(testing_id_addr_type_lut); i++) {

		params_vector = &testing_id_addr_type_lut[i];
		type = params_vector->type;
		id = params_vector->id;
		addr = params_vector->addr;

		returned_key = bt_keys_get_type(type, id, addr);
		returned_keys_refs[i] = returned_key;

		zassert_true(returned_key != NULL,
			     "bt_keys_get_type() failed to add key %d to the keys pool", i);
		zassert_true(returned_key->id == id,
			     "bt_keys_get_type() returned a reference with an incorrect ID");
		zassert_true(returned_key->keys == type,
			     "bt_keys_get_type() returned a reference with an incorrect key type");
		zassert_true(!bt_addr_le_cmp(&returned_key->addr, addr),
			     "bt_keys_get_type() returned incorrect address %s value, expected %s",
			     bt_addr_le_str(&returned_key->addr), bt_addr_le_str(addr));
	}
}

/*
 *  Test getting a non-existing key reference with type, ID and Address while the list is full.
 *
 *  Constraints:
 *   - Keys pool list is filled with items different from the ones used for testing
 *
 *  Expected behaviour:
 *   - A NULL value is returned by bt_keys_get_type()
 */
ZTEST(bt_keys_get_type_initially_filled_list, test_get_non_existing_key_reference_full_list)
{
	struct bt_keys *returned_key;
	int type = BT_KEYS_IRK;
	uint8_t id = BT_ADDR_ID_5;
	const bt_addr_le_t *addr = BT_ADDR_LE_5;

	returned_key = bt_keys_get_type(type, id, addr);

	zassert_true(returned_key == NULL, "bt_keys_get_type() returned a non-NULL reference");
}

/*
 *  Test getting an existing key reference with type, ID and Address while the list is full.
 *
 *  Constraints:
 *   - Keys pool list is filled with the ID and address pairs used
 *
 *  Expected behaviour:
 *   - A valid reference is returned by bt_keys_get_type()
 *   - Key reference returned matches the previously returned one
 *     when it was firstly inserted in the the list
 */
ZTEST(bt_keys_get_type_initially_filled_list, test_get_existing_key_reference)
{
	struct bt_keys *returned_key, *expected_key_ref;
	int type;
	uint8_t id;
	bt_addr_le_t *addr;
	struct id_addr_type const *params_vector;

	for (size_t i = 0; i < ARRAY_SIZE(testing_id_addr_type_lut); i++) {

		params_vector = &testing_id_addr_type_lut[i];
		type = params_vector->type;
		id = params_vector->id;
		addr = params_vector->addr;

		returned_key = bt_keys_get_type(type, id, addr);
		expected_key_ref = returned_keys_refs[i];

		zassert_true(returned_key != NULL,
			     "bt_keys_get_type() failed to add key %d to the keys pool", i);
		zassert_equal_ptr(returned_key, expected_key_ref,
				  "bt_keys_get_type() returned unexpected reference");
	}
}
