/*
 * Copyright (c) 2019 Bose Corporation
 * Copyright (c) 2020-2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifdef CONFIG_BT_CSIS_CLIENT
#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/audio/csis.h>
#include "common.h"

extern enum bst_result_t bst_result;
static volatile bool is_connected;
static volatile bool discovered;
static volatile bool members_discovered;
static volatile bool set_locked;
static volatile bool set_unlocked;
static volatile bool set_read_locked;
static volatile bool set_read_unlocked;
static struct bt_csis_client_csis_inst *inst;

static uint8_t members_found;
static struct k_work_delayable discover_members_timer;
static bt_addr_le_t addr_found[CONFIG_BT_MAX_CONN];
static struct bt_csis_client_set_member set_members[CONFIG_BT_MAX_CONN];

static void csis_client_lock_set_cb(int err);

static void csis_client_lock_release_cb(int err)
{
	printk("%s\n", __func__);

	if (err != 0) {
		FAIL("Release sets failed (%d)\n", err);
		return;
	}

	set_unlocked = true;
}

static void csis_client_lock_set_cb(int err)
{
	printk("%s\n", __func__);

	if (err != 0) {
		FAIL("Lock sets failed (%d)\n", err);
		return;
	}

	set_locked = true;
}

static void csis_discover_cb(struct bt_csis_client_set_member *member, int err,
			     uint8_t set_count)
{
	printk("%s\n", __func__);

	if (err != 0) {
		FAIL("Init failed (%d)\n", err);
		return;
	}

	inst = &member->insts[0];
	discovered = true;
}

static void csis_lock_changed_cb(struct bt_csis_client_csis_inst *inst,
				 bool locked)
{
	printk("Inst %p %s\n", inst, locked ? "locked" : "released");
}


static void csis_client_lock_state_read_cb(const struct bt_csis_client_set_info *set_info,
					   int err, bool locked)
{
	printk("%s\n", __func__);

	if (err != 0) {
		FAIL("read lock state failed (%d)\n", err);
		return;
	}

	if (locked) {
		set_read_locked = true;
	} else {
		set_read_unlocked = true;
	}
}

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

	if (is_connected) {
		return;
	}

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

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

	printk("Connected to %s\n", addr);
	is_connected = true;
}

static struct bt_conn_cb conn_callbacks = {
	.connected = connected,
};

static struct bt_csis_client_cb cbs = {
	.lock_set = csis_client_lock_set_cb,
	.release_set = csis_client_lock_release_cb,
	.discover = csis_discover_cb,
	.lock_changed = csis_lock_changed_cb,
	.lock_state_read = csis_client_lock_state_read_cb,
};

static bool is_discovered(const bt_addr_le_t *addr)
{
	for (int i = 0; i < members_found; i++) {
		if (bt_addr_le_cmp(addr, &addr_found[i]) == 0) {
			return true;
		}
	}
	return false;
}

static bool csis_found(struct bt_data *data, void *user_data)
{
	if (bt_csis_client_is_set_member(inst->info.set_sirk, data)) {
		const bt_addr_le_t *addr = user_data;
		char addr_str[BT_ADDR_LE_STR_LEN];

		bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
		printk("Found CSIS advertiser with address %s\n", addr_str);

		if (is_discovered(addr)) {
			printk("Set member already found\n");
			/* Stop parsing */
			return false;
		}

		bt_addr_le_copy(&addr_found[members_found++], addr);

		printk("Found member (%u / %u)\n",
		       members_found, inst->info.set_size);

		/* Stop parsing */
		return false;
	}
	/* Continue parsing */
	return true;
}

static void csis_client_scan_recv(const struct bt_le_scan_recv_info *info,
				  struct net_buf_simple *ad)
{
	/* We're only interested in connectable events */
	if (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) {
		if (inst == NULL) {
			/* Scanning for the first device */
			if (members_found == 0) {
				bt_addr_le_copy(&addr_found[members_found++],
						info->addr);
			}
		} else { /* Scanning for set members */
			bt_data_parse(ad, csis_found, (void *)info->addr);
		}
	}
}

static struct bt_le_scan_cb csis_client_scan_callbacks = {
	.recv = csis_client_scan_recv
};

static void discover_members_timer_handler(struct k_work *work)
{
	FAIL("Could not find all members (%u / %u)\n",
	     members_found, inst->info.set_size);
}

static void read_set_lock_state(const struct bt_csis_client_set_member **members,
				uint8_t count, bool expect_locked)
{
	int err;

	printk("Reading set state, expecting %s\n",
	       expect_locked ? "locked" : "unlocked");

	if (expect_locked) {
		set_read_locked = false;
	} else {
		set_read_unlocked = false;
	}

	err = bt_csis_client_get_lock_state(members, count, &inst->info);
	if (err != 0) {
		FAIL("Failed to do CSIS client read lock state (%d)", err);
		return;
	}

	if (expect_locked) {
		WAIT_FOR_COND(set_read_locked);
	} else {
		WAIT_FOR_COND(set_read_unlocked);
	}
}

static void test_main(void)
{
	int err;
	char addr[BT_ADDR_LE_STR_LEN];
	const struct bt_csis_client_set_member *locked_members[CONFIG_BT_MAX_CONN];
	uint8_t connected_member_count = 0;

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

	printk("Audio Client: Bluetooth initialized\n");

	bt_conn_cb_register(&conn_callbacks);
	bt_csis_client_register_cb(&cbs);
	k_work_init_delayable(&discover_members_timer,
			      discover_members_timer_handler);
	bt_le_scan_cb_register(&csis_client_scan_callbacks);

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

	printk("Scanning successfully started\n");

	WAIT_FOR_COND(members_found == 1);

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

	bt_addr_le_to_str(&addr_found[0], addr, sizeof(addr));
	err = bt_conn_le_create(&addr_found[0], BT_CONN_LE_CREATE_CONN,
				BT_LE_CONN_PARAM_DEFAULT, &set_members[0].conn);
	if (err != 0) {
		FAIL("Failed to connect to %s: %d\n", err);
		return;
	}
	printk("Connecting to %s\n", addr);

	WAIT_FOR_COND(is_connected);
	connected_member_count++;

	err = bt_csis_client_discover(&set_members[0]);
	if (err != 0) {
		FAIL("Failed to initialize CSIS client for connection %d\n",
		     err);
		return;
	}

	WAIT_FOR_COND(discovered);

	err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
	if (err != 0) {
		FAIL("Could not start scan: %d", err);
		return;
	}

	err = k_work_reschedule(&discover_members_timer,
				CSIS_CLIENT_DISCOVER_TIMER_VALUE);
	if (err < 0) { /* Can return 0, 1 and 2 for success */
		FAIL("Could not schedule discover_members_timer %d", err);
		return;
	}

	WAIT_FOR_COND(members_found == inst->info.set_size);

	(void)k_work_cancel_delayable(&discover_members_timer);
	err = bt_le_scan_stop();
	if (err != 0) {
		FAIL("Scanning failed to stop (err %d)\n", err);
		return;
	}

	for (uint8_t i = 1; i < members_found; i++) {
		bt_addr_le_to_str(&addr_found[i], addr, sizeof(addr));

		is_connected = false;
		printk("Connecting to member[%d] (%s)", i, addr);
		err = bt_conn_le_create(&addr_found[i],
					BT_CONN_LE_CREATE_CONN,
					BT_LE_CONN_PARAM_DEFAULT,
					&set_members[i].conn);
		if (err != 0) {
			FAIL("Failed to connect to %s: %d\n", addr, err);
			return;
		}

		printk("Connected to %s\n", addr);
		WAIT_FOR_COND(is_connected);
		connected_member_count++;

		discovered = false;
		printk("Doing discovery on member[%u]", i);
		err = bt_csis_client_discover(&set_members[i]);
		if (err != 0) {
			FAIL("Failed to initialize CSIS client for connection %d\n",
			      err);
			return;
		}

		WAIT_FOR_COND(discovered);
	}

	for (size_t i = 0; i < ARRAY_SIZE(locked_members); i++) {
		locked_members[i] = &set_members[i];
	}

	read_set_lock_state(locked_members, connected_member_count, false);

	printk("Locking set\n");
	err = bt_csis_client_lock(locked_members, connected_member_count,
				  &inst->info);
	if (err != 0) {
		FAIL("Failed to do CSIS client lock (%d)", err);
		return;
	}

	WAIT_FOR_COND(set_locked);

	read_set_lock_state(locked_members, connected_member_count, true);

	k_sleep(K_MSEC(1000)); /* Simulate doing stuff */

	printk("Releasing set\n");
	err = bt_csis_client_release(locked_members, connected_member_count,
				     &inst->info);
	if (err != 0) {
		FAIL("Failed to do CSIS client release (%d)", err);
		return;
	}

	WAIT_FOR_COND(set_unlocked);

	read_set_lock_state(locked_members, connected_member_count, false);

	/* Lock and unlock again */
	set_locked = false;
	set_unlocked = false;

	printk("Locking set\n");
	err = bt_csis_client_lock(locked_members, connected_member_count,
				  &inst->info);
	if (err != 0) {
		FAIL("Failed to do CSIS client lock (%d)", err);
		return;
	}

	WAIT_FOR_COND(set_locked);

	k_sleep(K_MSEC(1000)); /* Simulate doing stuff */

	printk("Releasing set\n");
	err = bt_csis_client_release(locked_members, connected_member_count,
				     &inst->info);
	if (err != 0) {
		FAIL("Failed to do CSIS client release (%d)", err);
		return;
	}

	WAIT_FOR_COND(set_unlocked);

	for (uint8_t i = 0; i < members_found; i++) {
		printk("Disconnecting member[%u] (%s)", i, addr);
		err = bt_conn_disconnect(set_members[i].conn,
					 BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		(void)memset(&set_members[i], 0, sizeof(set_members[i]));
		if (err != 0) {
			FAIL("Failed to do disconnect\n", err);
			return;
		}
	}

	PASS("All members disconnected\n");
}

static const struct bst_test_instance test_connect[] = {

	{
		.test_id = "csis_client",
		.test_post_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_main
	},

	BSTEST_END_MARKER
};

struct bst_test_list *test_csis_client_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_connect);
}
#else
struct bst_test_list *test_csis_client_install(struct bst_test_list *tests)
{
	return tests;
}

#endif /* CONFIG_BT_CSIS_CLIENT */
