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

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>

#include "common.h"

CREATE_FLAG(flag_is_connected);
CREATE_FLAG(flag_discover_complete);
CREATE_FLAG(flag_write_complete);
CREATE_FLAG(flag_chan_1_read);
CREATE_FLAG(flag_chan_2_read);
CREATE_FLAG(flag_db_hash_read);
CREATE_FLAG(flag_encrypted);

static struct bt_conn *g_conn;
static uint16_t chrc_handle;
static uint16_t csf_handle;
static const struct bt_uuid *test_svc_uuid = TEST_SERVICE_UUID;

static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (err != 0) {
		FAIL("Failed to connect to %s (%u)\n", addr, err);

		return;
	}

	printk("Connected to %s\n", addr);

	SET_FLAG(flag_is_connected);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (conn != g_conn) {
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);

	bt_conn_unref(g_conn);

	g_conn = NULL;
	UNSET_FLAG(flag_is_connected);
}

void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
{
	if (err != BT_SECURITY_ERR_SUCCESS) {
		FAIL("Encryption failed\n");
	} else if (level < BT_SECURITY_L2) {
		FAIL("Insufficient security\n");
	} else {
		SET_FLAG(flag_encrypted);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
	.security_changed = security_changed,
};

void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, struct net_buf_simple *ad)
{
	char addr_str[BT_ADDR_LE_STR_LEN];
	int err;

	if (g_conn != NULL) {
		return;
	}

	/* We're only interested in connectable events */
	if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) {
		return;
	}

	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
	printk("Device found: %s (RSSI %d)\n", addr_str, rssi);

	printk("Stopping scan\n");
	err = bt_le_scan_stop();
	if (err != 0) {
		FAIL("Could not stop scan (err %d)\n");

		return;
	}

	err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn);
	if (err != 0) {
		FAIL("Could not connect to peer (err %d)", err);
	}
}

static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	int err;

	if (attr == NULL) {
		if (chrc_handle == 0) {
			FAIL("Did not discover chrc (%x)\n", chrc_handle);
		}

		(void)memset(params, 0, sizeof(*params));

		SET_FLAG(flag_discover_complete);

		return BT_GATT_ITER_STOP;
	}

	printk("[ATTRIBUTE] handle %u\n", attr->handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY &&
	    bt_uuid_cmp(params->uuid, TEST_SERVICE_UUID) == 0) {
		printk("Found test service\n");
		params->uuid = NULL;
		params->start_handle = attr->handle + 1;
		params->type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, params);
		if (err != 0) {
			FAIL("Discover failed (err %d)\n", err);
		}

		return BT_GATT_ITER_STOP;
	} else if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data;

		if (bt_uuid_cmp(chrc->uuid, TEST_CHRC_UUID) == 0) {
			printk("Found chrc\n");
			chrc_handle = chrc->value_handle;

		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_CLIENT_FEATURES) == 0) {
			printk("Found csf\n");
			csf_handle = chrc->value_handle;
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static void gatt_discover(const struct bt_uuid *uuid, uint8_t type)
{
	static struct bt_gatt_discover_params discover_params;
	int err;

	printk("Discovering services and characteristics\n");

	discover_params.uuid = uuid;
	discover_params.func = discover_func;
	discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	discover_params.type = type;

	UNSET_FLAG(flag_discover_complete);

	err = bt_gatt_discover(g_conn, &discover_params);
	if (err != 0) {
		FAIL("Discover failed(err %d)\n", err);
	}

	WAIT_FOR_FLAG(flag_discover_complete);
	printk("Discover complete\n");
}
static struct bt_gatt_read_params chan_1_read = {
	.handle_count = 1,
	.single = {
		.handle = 0, /* Will be set later */
		.offset = 0,
	},
};
static struct bt_gatt_read_params chan_2_read = {
	.handle_count = 1,
	.single = {
		.handle = 0, /* Will be set later */
		.offset = 0,
	},
};
static struct bt_gatt_read_params db_hash_read = {
	.handle_count = 0,
	.by_uuid = {
		.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE,
		.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE,
		.uuid = BT_UUID_GATT_DB_HASH,
	},
};

void expect_status(uint8_t err, uint8_t status)
{
	if (err != status) {
		FAIL("Unexpected status from read: 0x%02X, expected 0x%02X\n", err, status);
	}
}

static uint8_t gatt_read_expect_success_cb(struct bt_conn *conn, uint8_t err,
					   struct bt_gatt_read_params *params, const void *data,
					   uint16_t length)
{
	printk("GATT read cb: err 0x%02X\n", err);
	expect_status(err, BT_ATT_ERR_SUCCESS);

	if (params == &db_hash_read) {
		SET_FLAG(flag_db_hash_read);
	} else if (params == &chan_1_read) {
		SET_FLAG(flag_chan_1_read);
	} else if (params == &chan_2_read) {
		SET_FLAG(flag_chan_2_read);
	} else {
		FAIL("Unexpected params\n");
	}

	return 0;
}

static uint8_t gatt_read_expect_err_unlikely_cb(struct bt_conn *conn, uint8_t err,
						struct bt_gatt_read_params *params,
						const void *data, uint16_t length)
{
	printk("GATT read cb: err 0x%02X\n", err);
	expect_status(err, BT_ATT_ERR_UNLIKELY);

	if (params == &chan_1_read) {
		SET_FLAG(flag_chan_1_read);
	} else if (params == &chan_2_read) {
		SET_FLAG(flag_chan_2_read);
	} else {
		FAIL("Unexpected params\n");
	}

	return 0;
}

static uint8_t gatt_read_expect_err_out_of_sync_cb(struct bt_conn *conn, uint8_t err,
						   struct bt_gatt_read_params *params,
						   const void *data, uint16_t length)
{
	printk("GATT read cb: err 0x%02X\n", err);
	expect_status(err, BT_ATT_ERR_DB_OUT_OF_SYNC);

	if (params == &chan_1_read) {
		SET_FLAG(flag_chan_1_read);
	} else if (params == &chan_2_read) {
		SET_FLAG(flag_chan_2_read);
	} else {
		FAIL("Unexpected params\n");
	}

	return 0;
}

static void gatt_read(struct bt_gatt_read_params *read_params)
{
	int err;

	printk("Reading\n");

	err = bt_gatt_read(g_conn, read_params);
	if (err != 0) {
		FAIL("bt_gatt_read failed: %d\n", err);
	}
}

static void write_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{
	if (err != BT_ATT_ERR_SUCCESS) {
		FAIL("Write failed: 0x%02X\n", err);
	}

	SET_FLAG(flag_write_complete);
}

static void enable_robust_caching(void)
{
	/* Client Supported Features Characteristic Value
	 * Bit 0: Robust Caching
	 * Bit 1: EATT
	 */
	static const uint8_t csf[] = { BIT(0) | BIT(1) };
	static struct bt_gatt_write_params write_params = {
		.func = write_cb,
		.offset = 0,
		.data = csf,
		.length = sizeof(csf),
	};
	int err;

	printk("Writing to Client Supported Features Characteristic\n");

	write_params.handle = csf_handle;
	UNSET_FLAG(flag_write_complete);

	err = bt_gatt_write(g_conn, &write_params);
	if (err) {
		FAIL("bt_gatt_write failed (err %d)\n", err);
	}

	WAIT_FOR_FLAG(flag_write_complete);
	printk("Success\n");
}

static void test_main_common(bool connect_eatt)
{
	int err;

	backchannel_init();

	err = bt_enable(NULL);
	if (err != 0) {
		FAIL("Bluetooth discover failed (err %d)\n", err);
	}

	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
	if (err != 0) {
		FAIL("Scanning failed to start (err %d)\n", err);
	}

	printk("Scanning successfully started\n");

	WAIT_FOR_FLAG(flag_is_connected);

	err = bt_conn_set_security(g_conn, BT_SECURITY_L2);
	if (err) {
		FAIL("Failed to start encryption procedure\n");
	}

	WAIT_FOR_FLAG(flag_encrypted);

	gatt_discover(test_svc_uuid, BT_GATT_DISCOVER_PRIMARY);
	gatt_discover(BT_UUID_GATT_CLIENT_FEATURES, BT_GATT_DISCOVER_CHARACTERISTIC);

	enable_robust_caching();

	if (connect_eatt) {
		while (bt_eatt_count(g_conn) < 1) {
			/* Wait for EATT channel to connect, in case it hasn't already */
			k_sleep(K_MSEC(10));
		}
	}

	/* Tell the server to register additional service */
	backchannel_sync_send();

	/* Wait for new service to be added by server */
	backchannel_sync_wait();

	chan_1_read.single.handle = chrc_handle;
	chan_2_read.single.handle = chrc_handle;
}

static void test_main_db_hash_read_eatt(void)
{
	test_main_common(true);

	/* Read the DB hash to become change-aware */
	db_hash_read.func = gatt_read_expect_success_cb;
	gatt_read(&db_hash_read);
	WAIT_FOR_FLAG(flag_db_hash_read);

	/* These shall now succeed */
	chan_1_read.func = gatt_read_expect_success_cb;
	chan_2_read.func = gatt_read_expect_success_cb;
	UNSET_FLAG(flag_chan_1_read);
	UNSET_FLAG(flag_chan_2_read);
	gatt_read(&chan_1_read);
	gatt_read(&chan_2_read);
	WAIT_FOR_FLAG(flag_chan_1_read);
	WAIT_FOR_FLAG(flag_chan_2_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static void test_main_out_of_sync_eatt(void)
{
	test_main_common(true);

	chan_1_read.func = gatt_read_expect_err_out_of_sync_cb;
	chan_2_read.func = gatt_read_expect_err_out_of_sync_cb;
	gatt_read(&chan_1_read);
	gatt_read(&chan_2_read);

	/* Wait until received response on both reads. When robust caching is implemented
	 * on the client side, the waiting shall be done automatically by the host when
	 * reading the DB hash.
	 */
	WAIT_FOR_FLAG(flag_chan_1_read);
	WAIT_FOR_FLAG(flag_chan_2_read);

	/* Read the DB hash to become change-aware */
	db_hash_read.func = gatt_read_expect_success_cb;
	gatt_read(&db_hash_read);
	WAIT_FOR_FLAG(flag_db_hash_read);

	/* These shall now succeed */
	chan_1_read.func = gatt_read_expect_success_cb;
	chan_2_read.func = gatt_read_expect_success_cb;
	UNSET_FLAG(flag_chan_1_read);
	UNSET_FLAG(flag_chan_2_read);
	gatt_read(&chan_1_read);
	gatt_read(&chan_2_read);
	WAIT_FOR_FLAG(flag_chan_1_read);
	WAIT_FOR_FLAG(flag_chan_2_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static void test_main_retry_reads_eatt(void)
{
	test_main_common(true);

	chan_1_read.func = gatt_read_expect_err_out_of_sync_cb;
	chan_2_read.func = gatt_read_expect_err_out_of_sync_cb;
	gatt_read(&chan_1_read);
	gatt_read(&chan_2_read);

	/* Wait until received response on both reads. When robust caching is implemented
	 * on the client side, the waiting shall be done automatically by the host when
	 * reading the DB hash.
	 */
	WAIT_FOR_FLAG(flag_chan_1_read);
	WAIT_FOR_FLAG(flag_chan_2_read);

	/* Retry the reads, these shall time out */
	chan_1_read.func = gatt_read_expect_err_unlikely_cb;
	chan_2_read.func = gatt_read_expect_err_unlikely_cb;
	UNSET_FLAG(flag_chan_1_read);
	UNSET_FLAG(flag_chan_2_read);
	gatt_read(&chan_1_read);
	gatt_read(&chan_2_read);
	WAIT_FOR_FLAG(flag_chan_1_read);
	WAIT_FOR_FLAG(flag_chan_2_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static void test_main_db_hash_read_no_eatt(void)
{
	test_main_common(false);

	/* Read the DB hash to become change-aware */
	db_hash_read.func = gatt_read_expect_success_cb;
	gatt_read(&db_hash_read);
	WAIT_FOR_FLAG(flag_db_hash_read);

	/* Read shall now succeed */
	chan_1_read.func = gatt_read_expect_success_cb;
	UNSET_FLAG(flag_chan_1_read);
	gatt_read(&chan_1_read);
	WAIT_FOR_FLAG(flag_chan_1_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static void test_main_out_of_sync_no_eatt(void)
{
	test_main_common(false);

	chan_1_read.func = gatt_read_expect_err_out_of_sync_cb;
	gatt_read(&chan_1_read);
	WAIT_FOR_FLAG(flag_chan_1_read);

	/* Read the DB hash to become change-aware */
	db_hash_read.func = gatt_read_expect_success_cb;
	gatt_read(&db_hash_read);
	WAIT_FOR_FLAG(flag_db_hash_read);

	/* Read shall now succeed */
	chan_1_read.func = gatt_read_expect_success_cb;
	UNSET_FLAG(flag_chan_1_read);
	gatt_read(&chan_1_read);
	WAIT_FOR_FLAG(flag_chan_1_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static void test_main_retry_reads_no_eatt(void)
{
	test_main_common(false);

	chan_1_read.func = gatt_read_expect_err_out_of_sync_cb;
	gatt_read(&chan_1_read);
	WAIT_FOR_FLAG(flag_chan_1_read);

	/* Read again to become change-aware */
	chan_1_read.func = gatt_read_expect_success_cb;
	UNSET_FLAG(flag_chan_1_read);
	gatt_read(&chan_1_read);
	WAIT_FOR_FLAG(flag_chan_1_read);

	/* Signal to server that reads are done */
	backchannel_sync_send();

	PASS("GATT client Passed\n");
}

static const struct bst_test_instance test_vcs[] = {
	{
		.test_id = "gatt_client_db_hash_read_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_db_hash_read_eatt,
	},
	{
		.test_id = "gatt_client_out_of_sync_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_out_of_sync_eatt,
	},
	{
		.test_id = "gatt_client_retry_reads_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_retry_reads_eatt,
	},
	{
		.test_id = "gatt_client_db_hash_read_no_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_db_hash_read_no_eatt,
	},
	{
		.test_id = "gatt_client_out_of_sync_no_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_out_of_sync_no_eatt,
	},
	{
		.test_id = "gatt_client_retry_reads_no_eatt",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main_retry_reads_no_eatt,
	},
	BSTEST_END_MARKER,
};

struct bst_test_list *test_gatt_client_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_vcs);
}
