/*
 * Copyright (c) 2019 Bose Corporation
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifdef CONFIG_BT_TBS_CLIENT

#include <zephyr/bluetooth/audio/tbs.h>

#include "common.h"

static struct bt_conn_cb conn_callbacks;
extern enum bst_result_t bst_result;

static volatile uint8_t call_state;
static volatile uint8_t call_index;
static volatile uint8_t tbs_count;

CREATE_FLAG(bt_init);
CREATE_FLAG(is_connected);
CREATE_FLAG(discovery_complete);
CREATE_FLAG(is_gtbs_found);
CREATE_FLAG(read_complete);
CREATE_FLAG(call_placed);
CREATE_FLAG(call_terminated);
CREATE_FLAG(provider_name);
CREATE_FLAG(ccid_read_flag);
CREATE_FLAG(signal_strength);
CREATE_FLAG(technology);
CREATE_FLAG(status_flags);
CREATE_FLAG(signal_interval);
CREATE_FLAG(call_accepted);
CREATE_FLAG(bearer_uci);
CREATE_FLAG(uri_list);
CREATE_FLAG(current_calls);
CREATE_FLAG(uri_inc);
CREATE_FLAG(term_reason);

static void tbs_client_call_states_cb(struct bt_conn *conn, int err,
				      uint8_t index, uint8_t call_count,
				      const struct bt_tbs_client_call_state *call_states)
{
	if (index != 0) {
		return;
	}

	printk("Index %u\n", __func__, index);
	if (err != 0) {
		FAIL("Call could not read call states (%d)\n", err);
		return;
	}

	call_index = call_states[0].index;
	call_state = call_states[0].state;
	printk("call index %u - state %u\n", call_index, call_state);
}

static void tbs_client_read_bearer_provider_name(struct bt_conn *conn, int err,
						 uint8_t index,
						 const char *value)
{
	if (err != 0) {
		FAIL("Call could not read bearer name (%d)\n", err);
		return;
	}

	printk("Index %u\n", index);
	printk("Bearer name pointer: %p\n", value);
	printk("Bearer name: %s\n", value);
	read_complete = true;
	SET_FLAG(provider_name);
}

static void tbs_client_discover_cb(struct bt_conn *conn, int err,
				   uint8_t count, bool gtbs_found)
{
	printk("%s\n", __func__);

	if (err != 0) {
		FAIL("TBS_CLIENT could not be discovered (%d)\n", err);
		return;
	}

	tbs_count = count;
	is_gtbs_found = true;
	discovery_complete = true;
}

static void tbs_client_read_ccid_cb(struct bt_conn *conn, int err,
				    uint8_t inst_index, uint32_t value)
{
	struct bt_tbs_instance *inst;

	if (value > UINT8_MAX) {
		FAIL("Invalid CCID: %u", value);
		return;
	}

	printk("Read CCID %u on index %u\n", value, inst_index);

	inst = bt_tbs_client_get_by_ccid(conn, (uint8_t)value);
	if (inst == NULL) {
		FAIL("Could not get instance by CCID: %u", value);
		return;
	}

	SET_FLAG(ccid_read_flag);
}

static void tbs_client_originate_call_cb(struct bt_conn *conn, int err,
					 uint8_t inst_index,
					 uint8_t call_index)
{
	printk("%s %u:\n", __func__, call_index);
	call_placed = true;
}

static void tbs_client_hold_call_cb(struct bt_conn *conn, int err,
				    uint8_t inst_index,
				    uint8_t call_index)
{
	if (err != 0) {
		FAIL("Client hold call error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
						  call_index);
}

static void tbs_client_retrieve_call_cb(struct bt_conn *conn, int err,
				    uint8_t inst_index,
				    uint8_t call_index)
{
	if (err != 0) {
		FAIL("Client retrieve call error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
						  call_index);
}

static void tbs_client_technology_cb(struct bt_conn *conn, int err,
				    uint8_t inst_index,
				    uint32_t value)
{
	if (err != 0) {
		FAIL("Client bearer technology error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Technology: %u\n", __func__, inst_index,
						  technology);

	SET_FLAG(technology);
}

static void tbs_client_signal_strength_cb(struct bt_conn *conn, int err,
					  uint8_t inst_index,
					  uint32_t value)
{
	if (err != 0) {
		FAIL("Client signal strength error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u, Strength: %u\n", __func__, inst_index,
						 signal_strength);

	SET_FLAG(signal_strength);
}

static void tbs_client_signal_interval_cb(struct bt_conn *conn, int err,
					  uint8_t inst_index,
					  uint32_t value)
{
	if (err != 0) {
		FAIL("Client signal interval error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Interval: %u\n", __func__, inst_index, value);

	SET_FLAG(signal_interval);
}

static void tbs_client_status_flags_cb(struct bt_conn *conn, int err,
				       uint8_t inst_index,
				       uint32_t value)
{
	if (err != 0) {
		FAIL("Status flags error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Flags: %u\n", __func__, inst_index,
					     status_flags);

	SET_FLAG(status_flags);
}

static void tbs_client_terminate_call_cb(struct bt_conn *conn, int err,
					 uint8_t inst_index, uint8_t call_index)
{
	if (err != 0) {
		FAIL("Terminate call error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
						  call_index);

	SET_FLAG(call_terminated);
}

static void tbs_client_accept_call_cb(struct bt_conn *conn, int err,
				      uint8_t inst_index, uint8_t call_index)
{
	if (err != 0) {
		FAIL("Accept call error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Call index: %u\n", __func__, inst_index,
						  call_index);

	SET_FLAG(call_accepted);
}

static void tbs_client_bearer_uci_cb(struct bt_conn *conn, int err,
				     uint8_t inst_index,
				     const char *value)
{
	if (err != 0) {
		FAIL("Bearer UCI error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u UCI: %u\n", __func__, inst_index, value);

	SET_FLAG(bearer_uci);
}

static void tbs_client_uri_list_cb(struct bt_conn *conn, int err,
				    uint8_t inst_index, const char *value)
{
	if (err != 0) {
		FAIL("URI list error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u URI list: %u\n", __func__, inst_index,
						uri_list);

	SET_FLAG(uri_list);
}

static void tbs_client_current_calls_cb(struct bt_conn *conn, int err,
					uint8_t inst_index,
					uint8_t call_count,
					const struct bt_tbs_client_call *calls)
{
	if (err != 0) {
		FAIL("Current calls error: (%d)\n", err);
		return;
	}

	printk("%s Instance: %u Call count: %u\n", __func__, inst_index,
						  call_count);

	SET_FLAG(current_calls);
}

static void tbs_client_call_uri_cb(struct bt_conn *conn, int err,
				   uint8_t inst_index,
				   const char *value)
{
	if (err != 0) {
		FAIL("Incoming URI error: (%d)\n", err);
		return;
	}

	printk("Incoming URI callback\n");
	printk("%s Instance: %u URI: %u\n", __func__, inst_index, value);

	SET_FLAG(uri_inc);
}

static void tbs_client_term_reason_cb(struct bt_conn *conn,
				      int err, uint8_t inst_index,
				      uint8_t call_index,
				      uint8_t reason)
{
	printk("%s Instance: %u Reason: %u\n", __func__, inst_index, reason);

	SET_FLAG(term_reason);
}

static const struct bt_tbs_client_cb tbs_client_cbs = {
	.discover = tbs_client_discover_cb,
	.originate_call = tbs_client_originate_call_cb,
	.terminate_call = tbs_client_terminate_call_cb,
	.hold_call = tbs_client_hold_call_cb,
	.accept_call = tbs_client_accept_call_cb,
	.retrieve_call = tbs_client_retrieve_call_cb,
	.bearer_provider_name = tbs_client_read_bearer_provider_name,
	.bearer_uci = tbs_client_bearer_uci_cb,
	.technology = tbs_client_technology_cb,
	.uri_list = tbs_client_uri_list_cb,
	.signal_strength = tbs_client_signal_strength_cb,
	.signal_interval = tbs_client_signal_interval_cb,
	.current_calls = tbs_client_current_calls_cb,
	.ccid = tbs_client_read_ccid_cb,
	.status_flags = tbs_client_status_flags_cb,
	.call_uri = tbs_client_call_uri_cb,
	.call_state = tbs_client_call_states_cb,
	.termination_reason = tbs_client_term_reason_cb
};

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) {
		bt_conn_unref(default_conn);
		FAIL("Failed to connect to %s (%u)\n", addr, err);
		return;
	}

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

static void bt_ready(int err)
{
	if (err != 0) {
		FAIL("Bluetooth discover failed (err %d)\n", err);
		return;
	}

	bt_init = true;
}

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

static void test_ccid(void)
{
	if (is_gtbs_found) {
		int err;

		UNSET_FLAG(ccid_read_flag);
		printk("Reading GTBS CCID\n");

		err = bt_tbs_client_read_ccid(default_conn, BT_TBS_GTBS_INDEX);
		if (err != 0) {
			FAIL("Read GTBS CCID failed (%d)\n", err);
			return;
		}

		WAIT_FOR_FLAG(ccid_read_flag);
	}

	for (uint8_t i = 0; i < tbs_count; i++) {
		int err;

		UNSET_FLAG(ccid_read_flag);
		printk("Reading bearer CCID on index %u\n", i);

		err = bt_tbs_client_read_ccid(default_conn, i);
		if (err != 0) {
			FAIL("Read bearer CCID failed (%d)\n", err);
			return;
		}

		WAIT_FOR_FLAG(ccid_read_flag);
	}
}

static void test_signal_strength(uint8_t index)
{
	int err;

	UNSET_FLAG(signal_strength);

	printk("%s\n", __func__);

	err = bt_tbs_client_read_signal_strength(default_conn, index);
	if (err != 0) {
		FAIL("Read signal strength failed (%d)\n", err);
		return;
	}

	WAIT_FOR_FLAG(signal_strength);

	printk("Client read signal strength test success\n");
}

static void test_technology(uint8_t index)
{
	int err;

	UNSET_FLAG(technology);

	printk("%s\n", __func__);

	err = bt_tbs_client_read_technology(default_conn, index);
	if (err != 0) {
		FAIL("Read technology failed (%d)\n", err);
		return;
	}

	WAIT_FOR_FLAG(technology);

	printk("Client read technology test success\n");
}

static void test_status_flags(uint8_t index)
{
	int err;

	UNSET_FLAG(status_flags);

	printk("%s\n", __func__);

	err = bt_tbs_client_read_status_flags(default_conn, index);
	if (err != 0) {
		FAIL("Read status flags failed (%d)\n", err);
		return;
	}

	WAIT_FOR_FLAG(status_flags);

	printk("Client read status flags test success\n");
}

static void test_signal_interval(uint8_t index)
{
	int err;

	UNSET_FLAG(signal_interval);

	printk("%s\n", __func__);

	err = bt_tbs_client_read_signal_interval(default_conn, index);
	if (err != 0) {
		FAIL("Read signal interval failed (%d)\n", err);
		return;
	}

	WAIT_FOR_FLAG(signal_interval);

	printk("Client signal interval test success\n");
}

static void test_main(void)
{
	int err;
	int index = 0;
	int tbs_client_err;

	err = bt_enable(bt_ready);

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

	bt_conn_cb_register(&conn_callbacks);
	bt_tbs_client_register_cb(&tbs_client_cbs);

	WAIT_FOR_COND(bt_init);

	printk("Audio Server: Bluetooth discovered\n");

	err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, AD_SIZE, NULL, 0);
	if (err != 0) {
		FAIL("Advertising failed to start (err %d)\n", err);
		return;
	}

	printk("Advertising successfully started\n");

	WAIT_FOR_COND(is_connected);

	tbs_client_err = bt_tbs_client_discover(default_conn, true);
	if (tbs_client_err) {
		FAIL("Failed to discover TBS_CLIENT for connection %d", tbs_client_err);
	}

	WAIT_FOR_COND(discovery_complete);

	printk("GTBS %sfound\n", is_gtbs_found ? "" : "not ");

	printk("Placing call\n");
	err = bt_tbs_client_originate_call(default_conn, 0, "tel:123456789012");
	if (err != 0) {
		FAIL("Originate call failed (%d)\n", err);
	}

	/* Call transitions:
	 * 1) Dialing
	 * 2) Alerting
	 * 3) Active
	 * 4) Remotely Held
	 */
	printk("Waiting for remotely held\n");
	WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_REMOTELY_HELD);

	printk("Holding call\n");
	err = bt_tbs_client_hold_call(default_conn, index, call_index);
	if (err != 0) {
		FAIL("Hold call failed (%d)\n", err);
	}

	/* Call transitions:
	 * 1) Locally and remotely held
	 * 2) Locally held
	 */
	WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_LOCALLY_HELD);

	printk("Retrieving call\n");
	err = bt_tbs_client_retrieve_call(default_conn, index, call_index);
	if (err != 0) {
		FAIL("Retrieve call failed (%d)\n", err);
	}

	WAIT_FOR_COND(call_state == BT_TBS_CALL_STATE_ACTIVE);

	printk("Reading bearer provider name\n");
	UNSET_FLAG(provider_name);
	err = bt_tbs_client_read_bearer_provider_name(default_conn, index);
	if (err != 0) {
		FAIL("Read bearer provider name failed (%d)\n", err);
	}

	test_ccid();
	WAIT_FOR_COND(read_complete);

	test_signal_strength(index);
	test_technology(index);
	test_status_flags(index);
	test_signal_interval(index);

	PASS("TBS_CLIENT Passed\n");
}

static const struct bst_test_instance test_tbs_client[] = {
	{
		.test_id = "tbs_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_tbs_client_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_tbs_client);
}

#else
struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests)
{
	return tests;
}

#endif /* CONFIG_BT_TBS_CLIENT */
