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

#include <zephyr/sys/check.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/audio/tbs.h>
#include "cap_internal.h"
#include "csip_internal.h"
#include "bap_endpoint.h"

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_cap_initiator, CONFIG_BT_CAP_INITIATOR_LOG_LEVEL);

#include "common/bt_str.h"

static const struct bt_cap_initiator_cb *cap_cb;

int bt_cap_initiator_register_cb(const struct bt_cap_initiator_cb *cb)
{
	CHECKIF(cb == NULL) {
		LOG_DBG("cb is NULL");
		return -EINVAL;
	}

	CHECKIF(cap_cb != NULL) {
		LOG_DBG("callbacks already registered");
		return -EALREADY;
	}

	cap_cb = cb;

	return 0;
}

static bool cap_initiator_valid_metadata(const struct bt_codec_data meta[],
					 size_t meta_count)
{
	bool stream_context_found;

	LOG_DBG("meta %p count %zu", meta, meta_count);

	/* Streaming Audio Context shall be present in CAP */
	stream_context_found = false;
	for (size_t i = 0U; i < meta_count; i++) {
		const struct bt_data *metadata = &meta[i].data;

		LOG_DBG("metadata %p type %u len %u data %s",
			metadata, metadata->type, metadata->data_len,
			bt_hex(metadata->data, metadata->data_len));

		if (metadata->type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
			if (metadata->data_len != 2) { /* Stream context size */
				return false;
			}

			stream_context_found = true;
			break;
		}
	}

	if (!stream_context_found) {
		LOG_DBG("No streaming context supplied");
	}

	return stream_context_found;
}

#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
static struct bt_cap_broadcast_source {
	struct bt_bap_broadcast_source *bap_broadcast;
} broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT];

static bool cap_initiator_broadcast_audio_start_valid_param(
	const struct bt_cap_initiator_broadcast_create_param *param)
{

	for (size_t i = 0U; i < param->subgroup_count; i++) {
		const struct bt_cap_initiator_broadcast_subgroup_param *subgroup_param;
		const struct bt_codec *codec;
		bool valid_metadata;

		subgroup_param = &param->subgroup_params[i];
		codec = subgroup_param->codec;

		/* Streaming Audio Context shall be present in CAP */

		CHECKIF(codec == NULL) {
			LOG_DBG("subgroup[%zu]->codec is NULL", i);
			return false;
		}

		valid_metadata = cap_initiator_valid_metadata(codec->meta,
							      codec->meta_count);

		CHECKIF(!valid_metadata) {
			LOG_DBG("Invalid metadata supplied for subgroup[%zu]", i);
			return false;
		}
	}

	return true;
}

static void cap_initiator_broadcast_to_bap_broadcast_param(
	const struct bt_cap_initiator_broadcast_create_param *cap_param,
	struct bt_bap_broadcast_source_create_param *bap_param,
	struct bt_bap_broadcast_source_subgroup_param
		bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT],
	struct bt_bap_broadcast_source_stream_param
		bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT])
{
	size_t stream_cnt = 0U;

	bap_param->params_count = cap_param->subgroup_count;
	bap_param->params = bap_subgroup_params;
	bap_param->qos = cap_param->qos;
	bap_param->packing = cap_param->packing;
	bap_param->encryption = cap_param->encryption;
	if (bap_param->encryption) {
		memcpy(bap_param->broadcast_code, cap_param->broadcast_code,
		       BT_AUDIO_BROADCAST_CODE_SIZE);
	} else {
		memset(bap_param->broadcast_code, 0, BT_AUDIO_BROADCAST_CODE_SIZE);
	}

	for (size_t i = 0U; i < bap_param->params_count; i++) {
		const struct bt_cap_initiator_broadcast_subgroup_param *cap_subgroup_param =
			&cap_param->subgroup_params[i];
		struct bt_bap_broadcast_source_subgroup_param *bap_subgroup_param =
			&bap_param->params[i];

		bap_subgroup_param->codec = cap_subgroup_param->codec;
		bap_subgroup_param->params_count = cap_subgroup_param->stream_count;
		bap_subgroup_param->params = &bap_stream_params[stream_cnt];

		for (size_t j = 0U; j < bap_subgroup_param->params_count; j++, stream_cnt++) {
			const struct bt_cap_initiator_broadcast_stream_param *cap_stream_param =
				&cap_subgroup_param->stream_params[j];
			struct bt_bap_broadcast_source_stream_param *bap_stream_param =
				&bap_subgroup_param->params[j];

			bap_stream_param->stream = &cap_stream_param->stream->bap_stream;
#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0
			bap_stream_param->data_count = cap_stream_param->data_count;
			/* We do not need to copy the data, as that is the same type of struct, so
			 * we can just point to the CAP parameter data
			 */
			bap_stream_param->data = cap_stream_param->data;
#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */
		}
	}
}

int bt_cap_initiator_broadcast_audio_create(
	const struct bt_cap_initiator_broadcast_create_param *param,
	struct bt_cap_broadcast_source **broadcast_source)
{
	struct bt_bap_broadcast_source_subgroup_param
		bap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
	struct bt_bap_broadcast_source_stream_param
		bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
	struct bt_bap_broadcast_source_create_param bap_create_param;

	CHECKIF(param == NULL) {
		LOG_DBG("param is NULL");
		return -EINVAL;
	}

	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("source is NULL");
		return -EINVAL;
	}

	if (!cap_initiator_broadcast_audio_start_valid_param(param)) {
		return -EINVAL;
	}

	for (size_t i = 0; i < ARRAY_SIZE(broadcast_sources); i++) {
		if (broadcast_sources[i].bap_broadcast == NULL) {
			*broadcast_source = &broadcast_sources[i];
			break;
		}
	}

	cap_initiator_broadcast_to_bap_broadcast_param(param, &bap_create_param,
						       bap_subgroup_params, bap_stream_params);

	return bt_bap_broadcast_source_create(&bap_create_param,
					      &(*broadcast_source)->bap_broadcast);
}

int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broadcast_source,
					   struct bt_le_ext_adv *adv)
{
	CHECKIF(adv == NULL) {
		LOG_DBG("adv is NULL");
		return -EINVAL;
	}

	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	return bt_bap_broadcast_source_start(broadcast_source->bap_broadcast, adv);
}

int bt_cap_initiator_broadcast_audio_update(struct bt_cap_broadcast_source *broadcast_source,
					    const struct bt_codec_data meta[],
					    size_t meta_count)
{
	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	CHECKIF(meta == NULL) {
		LOG_DBG("meta is NULL");
		return -EINVAL;
	}

	if (!cap_initiator_valid_metadata(meta, meta_count)) {
		LOG_DBG("Invalid metadata");
		return -EINVAL;
	}

	return bt_bap_broadcast_source_update_metadata(broadcast_source->bap_broadcast, meta,
						       meta_count);
}

int bt_cap_initiator_broadcast_audio_stop(struct bt_cap_broadcast_source *broadcast_source)
{
	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	return bt_bap_broadcast_source_stop(broadcast_source->bap_broadcast);
}

int bt_cap_initiator_broadcast_audio_delete(struct bt_cap_broadcast_source *broadcast_source)
{
	int err;

	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	err = bt_bap_broadcast_source_delete(broadcast_source->bap_broadcast);
	if (err == 0) {
		broadcast_source->bap_broadcast = NULL;
	}

	return err;
}

int bt_cap_initiator_broadcast_get_id(const struct bt_cap_broadcast_source *broadcast_source,
				      uint32_t *const broadcast_id)
{
	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	return bt_bap_broadcast_source_get_id(broadcast_source->bap_broadcast, broadcast_id);
}

int bt_cap_initiator_broadcast_get_base(struct bt_cap_broadcast_source *broadcast_source,
					struct net_buf_simple *base_buf)
{
	CHECKIF(broadcast_source == NULL) {
		LOG_DBG("broadcast_source is NULL");
		return -EINVAL;
	}

	return bt_bap_broadcast_source_get_base(broadcast_source->bap_broadcast, base_buf);
}

#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */

#if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
enum {
	CAP_UNICAST_PROC_STATE_ACTIVE,
	CAP_UNICAST_PROC_STATE_ABORTED,

	CAP_UNICAST_PROC_STATE_FLAG_NUM,
} cap_unicast_proc_state;

enum cap_unicast_proc_type {
	CAP_UNICAST_PROC_TYPE_NONE,
	CAP_UNICAST_PROC_TYPE_START,
	CAP_UNICAST_PROC_TYPE_UPDATE,
	CAP_UNICAST_PROC_TYPE_STOP,
};

enum cap_unicast_subproc_type {
	CAP_UNICAST_SUBPROC_TYPE_NONE,
	CAP_UNICAST_SUBPROC_TYPE_CODEC_CONFIG,
	CAP_UNICAST_SUBPROC_TYPE_QOS_CONFIG,
	CAP_UNICAST_SUBPROC_TYPE_ENABLE,
	CAP_UNICAST_SUBPROC_TYPE_START,
	CAP_UNICAST_SUBPROC_TYPE_META_UPDATE,
	CAP_UNICAST_SUBPROC_TYPE_RELEASE,
};

struct cap_unicast_proc {
	ATOMIC_DEFINE(proc_state_flags, CAP_UNICAST_PROC_STATE_FLAG_NUM);
	/* Total number of streams in the procedure*/
	size_t stream_cnt;
	/* Number of streams where a subprocedure have been started */
	size_t stream_initiated_cnt;
	/* Number of streams done with the procedure */
	size_t stream_done_cnt;
	enum cap_unicast_proc_type proc_type;
	enum cap_unicast_subproc_type subproc_type;
	int err;
	struct bt_conn *failed_conn;
	struct bt_cap_stream *streams[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
	struct bt_bap_unicast_group *unicast_group;
};

struct cap_unicast_client {
	struct bt_conn *conn;
	struct bt_gatt_discover_params param;
	uint16_t csis_start_handle;
	const struct bt_csip_set_coordinator_csis_inst *csis_inst;
	bool cas_found;
};

static struct cap_unicast_client bt_cap_unicast_clients[CONFIG_BT_MAX_CONN];
static const struct bt_uuid *cas_uuid = BT_UUID_CAS;
static struct cap_unicast_proc active_proc;

static void cap_set_subproc(enum cap_unicast_subproc_type subproc_type)
{
	active_proc.stream_done_cnt = 0U;
	active_proc.stream_initiated_cnt = 0U;
	active_proc.subproc_type = subproc_type;
}

static bool cap_proc_is_active(void)
{
	return atomic_test_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ACTIVE);
}

static bool cap_proc_is_aborted(void)
{
	return atomic_test_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ABORTED);
}

static bool cap_proc_all_streams_handled(void)
{
	return active_proc.stream_done_cnt == active_proc.stream_initiated_cnt;
}

static bool cap_proc_is_done(void)
{
	return active_proc.stream_done_cnt == active_proc.stream_cnt;
}

static void cap_abort_proc(struct bt_conn *conn, int err)
{
	if (cap_proc_is_aborted()) {
		/* no-op */
		return;
	}

	active_proc.err = err;
	active_proc.failed_conn = conn;
	atomic_set_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ABORTED);
}

static bool cap_conn_in_active_proc(const struct bt_conn *conn)
{
	if (!cap_proc_is_active()) {
		return false;
	}

	for (size_t i = 0U; i < active_proc.stream_initiated_cnt; i++) {
		if (active_proc.streams[i]->bap_stream.conn == conn) {
			return true;
		}
	}

	return false;
}

static void cap_initiator_disconnected(struct bt_conn *conn, uint8_t reason)
{
	struct cap_unicast_client *client;

	client = &bt_cap_unicast_clients[bt_conn_index(conn)];

	if (client->conn != NULL) {
		bt_conn_unref(client->conn);
	}
	(void)memset(client, 0, sizeof(*client));

	if (cap_conn_in_active_proc(conn)) {
		cap_abort_proc(conn, -ENOTCONN);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.disconnected = cap_initiator_disconnected,
};

static struct cap_unicast_client *lookup_unicast_client_by_csis(
	const struct bt_csip_set_coordinator_csis_inst *csis_inst)
{
	if (csis_inst == NULL) {
		return NULL;
	}

	for (size_t i = 0U; i < ARRAY_SIZE(bt_cap_unicast_clients); i++) {
		struct cap_unicast_client *client = &bt_cap_unicast_clients[i];

		if (client->csis_inst == csis_inst) {
			return client;
		}
	}

	return NULL;
}

static void csis_client_discover_cb(struct bt_conn *conn,
				    const struct bt_csip_set_coordinator_set_member *member,
				    int err, size_t set_count)
{
	struct cap_unicast_client *client;

	if (err != 0) {
		LOG_DBG("CSIS client discover failed: %d", err);

		if (cap_cb && cap_cb->unicast_discovery_complete) {
			cap_cb->unicast_discovery_complete(conn, err, NULL);
		}

		return;
	}

	client = &bt_cap_unicast_clients[bt_conn_index(conn)];
	client->csis_inst = bt_csip_set_coordinator_csis_inst_by_handle(
					conn, client->csis_start_handle);

	if (member == NULL || set_count == 0 || client->csis_inst == NULL) {
		LOG_ERR("Unable to find CSIS for CAS");

		if (cap_cb && cap_cb->unicast_discovery_complete) {
			cap_cb->unicast_discovery_complete(conn, -ENODATA,
							   NULL);
		}
	} else {
		LOG_DBG("Found CAS with CSIS");
		if (cap_cb && cap_cb->unicast_discovery_complete) {
			cap_cb->unicast_discovery_complete(conn, 0,
							   client->csis_inst);
		}
	}
}

static uint8_t cap_unicast_discover_included_cb(struct bt_conn *conn,
						const struct bt_gatt_attr *attr,
						struct bt_gatt_discover_params *params)
{
	params->func = NULL;

	if (attr == NULL) {
		LOG_DBG("CAS CSIS include not found");

		if (cap_cb && cap_cb->unicast_discovery_complete) {
			cap_cb->unicast_discovery_complete(conn, 0, NULL);
		}
	} else {
		const struct bt_gatt_include *included_service = attr->user_data;
		struct cap_unicast_client *client = CONTAINER_OF(params,
								 struct cap_unicast_client,
								 param);

		/* If the remote CAS includes CSIS, we first check if we
		 * have already discovered it, and if so we can just retrieve it
		 * and forward it to the application. If not, then we start
		 * CSIS discovery
		 */
		client->csis_start_handle = included_service->start_handle;
		client->csis_inst = bt_csip_set_coordinator_csis_inst_by_handle(
					conn, client->csis_start_handle);

		if (client->csis_inst == NULL) {
			static struct bt_csip_set_coordinator_cb csis_client_cb = {
				.discover = csis_client_discover_cb
			};
			static bool csis_cbs_registered;
			int err;

			LOG_DBG("CAS CSIS not known, discovering");

			if (!csis_cbs_registered) {
				bt_csip_set_coordinator_register_cb(&csis_client_cb);
				csis_cbs_registered = true;
			}

			err = bt_csip_set_coordinator_discover(conn);
			if (err != 0) {
				LOG_DBG("Discover failed (err %d)", err);
				if (cap_cb && cap_cb->unicast_discovery_complete) {
					cap_cb->unicast_discovery_complete(conn,
									   err,
									   NULL);
				}
			}
		} else if (cap_cb && cap_cb->unicast_discovery_complete) {
			LOG_DBG("Found CAS with CSIS");
			cap_cb->unicast_discovery_complete(conn, 0,
							   client->csis_inst);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t cap_unicast_discover_cas_cb(struct bt_conn *conn,
				       const struct bt_gatt_attr *attr,
				       struct bt_gatt_discover_params *params)
{
	params->func = NULL;

	if (attr == NULL) {
		if (cap_cb && cap_cb->unicast_discovery_complete) {
			cap_cb->unicast_discovery_complete(conn, -ENODATA,
							   NULL);
		}
	} else {
		const struct bt_gatt_service_val *prim_service = attr->user_data;
		struct cap_unicast_client *client = CONTAINER_OF(params,
								 struct cap_unicast_client,
								 param);
		int err;

		client->cas_found = true;
		client->conn = bt_conn_ref(conn);

		if (attr->handle == prim_service->end_handle) {
			LOG_DBG("Found CAS without CSIS");
			cap_cb->unicast_discovery_complete(conn, 0, NULL);

			return BT_GATT_ITER_STOP;
		}

		LOG_DBG("Found CAS, discovering included CSIS");

		params->uuid = NULL;
		params->start_handle = attr->handle + 1;
		params->end_handle = prim_service->end_handle;
		params->type = BT_GATT_DISCOVER_INCLUDE;
		params->func = cap_unicast_discover_included_cb;

		err = bt_gatt_discover(conn, params);
		if (err != 0) {
			LOG_DBG("Discover failed (err %d)", err);

			params->func = NULL;
			if (cap_cb && cap_cb->unicast_discovery_complete) {
				cap_cb->unicast_discovery_complete(conn, err,
								   NULL);
			}
		}
	}

	return BT_GATT_ITER_STOP;
}

int bt_cap_initiator_unicast_discover(struct bt_conn *conn)
{
	struct bt_gatt_discover_params *param;
	int err;

	CHECKIF(conn == NULL) {
		LOG_DBG("NULL conn");
		return -EINVAL;
	}

	param = &bt_cap_unicast_clients[bt_conn_index(conn)].param;

	/* use param->func to tell if a client is "busy" */
	if (param->func != NULL) {
		return -EBUSY;
	}

	param->func = cap_unicast_discover_cas_cb;
	param->uuid = cas_uuid;
	param->type = BT_GATT_DISCOVER_PRIMARY;
	param->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	param->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	err = bt_gatt_discover(conn, param);
	if (err != 0) {
		param->func = NULL;
	}

	return err;
}

static bool cap_stream_in_active_proc(const struct bt_cap_stream *cap_stream)
{
	if (!cap_proc_is_active()) {
		return false;
	}

	for (size_t i = 0U; i < active_proc.stream_cnt; i++) {
		if (active_proc.streams[i] == cap_stream) {
			return true;
		}
	}

	return false;
}

static bool valid_unicast_audio_start_param(const struct bt_cap_unicast_audio_start_param *param,
					    struct bt_bap_unicast_group *unicast_group)
{
	CHECKIF(param == NULL) {
		LOG_DBG("param is NULL");
		return false;
	}

	CHECKIF(param->count == 0) {
		LOG_DBG("Invalid param->count: %u", param->count);
		return false;
	}

	CHECKIF(param->stream_params == NULL) {
		LOG_DBG("param->stream_params is NULL");
		return false;
	}

	CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
		LOG_DBG("param->count (%zu) is larger than "
			"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
			param->count,
			CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
		return false;
	}

	for (size_t i = 0U; i < param->count; i++) {
		const struct bt_cap_unicast_audio_start_stream_param *stream_param =
									&param->stream_params[i];
		const union bt_cap_set_member *member = &stream_param->member;
		const struct bt_cap_stream *cap_stream = stream_param->stream;
		const struct bt_codec *codec = stream_param->codec;
		const struct bt_bap_stream *bap_stream;

		CHECKIF(stream_param->codec == NULL) {
			LOG_DBG("param->stream_params[%zu].codec is NULL", i);
			return false;
		}

		CHECKIF(!cap_initiator_valid_metadata(codec->meta,
						      codec->meta_count)) {
			LOG_DBG("param->stream_params[%zu].codec is invalid",
				i);
			return false;
		}

		CHECKIF(stream_param->ep == NULL) {
			LOG_DBG("param->stream_params[%zu].ep is NULL", i);
			return false;
		}

		CHECKIF(stream_param->qos == NULL) {
			LOG_DBG("param->stream_params[%zu].qos is NULL", i);
			return false;
		}

		CHECKIF(member == NULL) {
			LOG_DBG("param->stream_params[%zu].member is NULL", i);
			return false;
		}

		if (param->type == BT_CAP_SET_TYPE_AD_HOC) {
			struct cap_unicast_client *client;

			CHECKIF(member->member == NULL) {
				LOG_DBG("param->members[%zu] is NULL", i);
				return false;
			}

			client = &bt_cap_unicast_clients[bt_conn_index(member->member)];

			if (!client->cas_found) {
				LOG_DBG("CAS was not found for param->members[%zu]", i);
				return false;
			}
		}

		if (param->type == BT_CAP_SET_TYPE_CSIP) {
			struct cap_unicast_client *client;

			CHECKIF(member->csip == NULL) {
				LOG_DBG("param->csip.set[%zu] is NULL", i);
				return false;
			}

			client = lookup_unicast_client_by_csis(member->csip);
			if (client == NULL) {
				LOG_DBG("CSIS was not found for param->members[%zu]", i);
				return false;
			}
		}

		CHECKIF(cap_stream == NULL) {
			LOG_DBG("param->streams[%zu] is NULL", i);
			return false;
		}

		bap_stream = &cap_stream->bap_stream;

		CHECKIF(bap_stream->ep != NULL) {
			LOG_DBG("param->streams[%zu] is already started", i);
			return false;
		}

		CHECKIF(bap_stream->group == NULL) {
			LOG_DBG("param->streams[%zu] is not in a unicast group", i);
			return false;
		}

		CHECKIF(bap_stream->group != unicast_group) {
			LOG_DBG("param->streams[%zu] is not in this group %p", i, unicast_group);
			return false;
		}

		for (size_t j = 0U; j < i; j++) {
			if (param->stream_params[j].stream == cap_stream) {
				LOG_DBG("param->stream_params[%zu] (%p) is "
					"duplicated by "
					"param->stream_params[%zu] (%p)",
					j, param->stream_params[j].stream,
					i, cap_stream);
				return false;
			}
		}
	}

	return true;
}

static int cap_initiator_unicast_audio_configure(
	const struct bt_cap_unicast_audio_start_param *param)
{
	/** TODO: If this is a CSIP set, then the order of the procedures may
	 * not match the order in the parameters, and the CSIP ordered access
	 * procedure should be used.
	 */

	/* Store the information about the active procedure so that we can
	 * continue the procedure after each step
	 */
	atomic_set_bit(active_proc.proc_state_flags, CAP_UNICAST_PROC_STATE_ACTIVE);
	active_proc.stream_cnt = param->count;

	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_CODEC_CONFIG);

	for (size_t i = 0U; i < param->count; i++) {
		struct bt_cap_unicast_audio_start_stream_param *stream_param =
									&param->stream_params[i];
		union bt_cap_set_member *member = &stream_param->member;
		struct bt_cap_stream *cap_stream = stream_param->stream;
		struct bt_bap_stream *bap_stream = &cap_stream->bap_stream;
		struct bt_bap_ep *ep = stream_param->ep;
		struct bt_codec *codec = stream_param->codec;
		struct bt_conn *conn;
		int err;

		if (param->type == BT_CAP_SET_TYPE_AD_HOC) {
			conn = member->member;
		} else {
			struct cap_unicast_client *client;

			/* We have verified that `client` wont be NULL in
			 * `valid_unicast_audio_start_param`.
			 */
			client = lookup_unicast_client_by_csis(member->csip);
			__ASSERT(client != NULL, "client is NULL");
			conn = client->conn;
		}

		/* Ensure that ops are registered before any procedures are started */
		bt_cap_stream_ops_register_bap(cap_stream);

		active_proc.streams[i] = cap_stream;

		err = bt_bap_stream_config(conn, bap_stream, ep, codec);
		if (err != 0) {
			LOG_DBG("bt_bap_stream_config failed for param->stream_params[%zu]: %d",
				i, err);

			if (i > 0U) {
				cap_abort_proc(bap_stream->conn, err);
			} else {
				(void)memset(&active_proc, 0, sizeof(active_proc));
			}

			return err;
		}

		active_proc.stream_initiated_cnt++;
	}

	return 0;
}

static void cap_initiator_unicast_audio_proc_complete(void)
{
	struct bt_bap_unicast_group *unicast_group;
	enum cap_unicast_proc_type proc_type;
	struct bt_conn *failed_conn;
	int err;

	unicast_group = active_proc.unicast_group;
	failed_conn = active_proc.failed_conn;
	err = active_proc.err;
	proc_type = active_proc.proc_type;
	(void)memset(&active_proc, 0, sizeof(active_proc));

	if (cap_cb == NULL) {
		return;
	}

	switch (proc_type) {
	case CAP_UNICAST_PROC_TYPE_START:
		if (cap_cb->unicast_start_complete != NULL) {
			cap_cb->unicast_start_complete(unicast_group, err, failed_conn);
		}
		break;
	case CAP_UNICAST_PROC_TYPE_UPDATE:
		if (cap_cb->unicast_update_complete != NULL) {
			cap_cb->unicast_update_complete(err, failed_conn);
		}
		break;
	case CAP_UNICAST_PROC_TYPE_STOP:
		if (cap_cb->unicast_stop_complete != NULL) {
			cap_cb->unicast_stop_complete(unicast_group, err, failed_conn);
		}
		break;
	case CAP_UNICAST_PROC_TYPE_NONE:
	default:
		__ASSERT(false, "Invalid proc_type: %u", proc_type);
	}
}

int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start_param *param,
					 struct bt_bap_unicast_group *unicast_group)
{
	if (cap_proc_is_active()) {
		LOG_DBG("A CAP procedure is already in progress");

		return -EBUSY;
	}

	CHECKIF(unicast_group == NULL) {
		LOG_DBG("unicast_group is NULL");
		return -EINVAL;
	}

	if (!valid_unicast_audio_start_param(param, unicast_group)) {
		return -EINVAL;
	}

	active_proc.unicast_group = unicast_group;
	active_proc.proc_type = CAP_UNICAST_PROC_TYPE_START;

	return cap_initiator_unicast_audio_configure(param);
}

void bt_cap_initiator_codec_configured(struct bt_cap_stream *cap_stream)
{
	struct bt_conn *conns[MIN(CONFIG_BT_MAX_CONN,
				  CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT)];
	struct bt_bap_unicast_group *unicast_group;

	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type == CAP_UNICAST_SUBPROC_TYPE_RELEASE) {
		/* When releasing a stream, it may go into the codec configured state if
		 * the unicast server caches the configuration - We treat it as a release
		 */
		bt_cap_initiator_released(cap_stream);
		return;
	} else if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_CODEC_CONFIG) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p configured (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);

		if (!cap_proc_is_done()) {
			/* Not yet finished, wait for all */
			return;
		}
	}

	if (cap_proc_is_aborted()) {
		if (cap_proc_all_streams_handled()) {
			cap_initiator_unicast_audio_proc_complete();
		}

		return;
	}

	/* The QoS Configure procedure works on a set of connections and a
	 * unicast group, so we generate a list of unique connection pointers
	 * for the procedure
	 */
	(void)memset(conns, 0, sizeof(conns));
	for (size_t i = 0U; i < active_proc.stream_cnt; i++) {
		struct bt_conn *stream_conn = active_proc.streams[i]->bap_stream.conn;
		struct bt_conn **free_conn = NULL;
		bool already_added = false;

		for (size_t j = 0U; j < ARRAY_SIZE(conns); j++) {
			if (stream_conn == conns[j]) {
				already_added = true;
				break;
			} else if (conns[j] == NULL && free_conn == NULL) {
				free_conn = &conns[j];
			}
		}

		if (already_added) {
			continue;
		}

		__ASSERT(free_conn, "No free conns");
		*free_conn = stream_conn;
	}

	/* All streams in the procedure share the same unicast group, so we just
	 * use the reference from the first stream
	 */
	unicast_group = (struct bt_bap_unicast_group *)active_proc.streams[0]->bap_stream.group;
	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_QOS_CONFIG);

	for (size_t i = 0U; i < ARRAY_SIZE(conns); i++) {
		int err;

		/* When conns[i] is NULL, we have QoS Configured all unique connections */
		if (conns[i] == NULL) {
			break;
		}

		err = bt_bap_stream_qos(conns[i], unicast_group);
		if (err != 0) {
			LOG_DBG("Failed to set stream QoS for conn %p and group %p: %d",
				(void *)conns[i], unicast_group, err);

			/* End or mark procedure as aborted.
			 * If we have sent any requests over air, we will abort
			 * once all sent requests has completed
			 */
			cap_abort_proc(conns[i], err);
			if (i == 0U) {
				cap_initiator_unicast_audio_proc_complete();
			}

			return;
		}

		active_proc.stream_initiated_cnt++;
	}
}

void bt_cap_initiator_qos_configured(struct bt_cap_stream *cap_stream)
{
	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_QOS_CONFIG) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p QoS configured (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);

		if (!cap_proc_is_done()) {
			/* Not yet finished, wait for all */
			return;
		}
	}

	if (cap_proc_is_aborted()) {
		if (cap_proc_all_streams_handled()) {
			cap_initiator_unicast_audio_proc_complete();
		}

		return;
	}

	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_ENABLE);

	for (size_t i = 0U; i < active_proc.stream_cnt; i++) {
		struct bt_cap_stream *cap_stream_active = active_proc.streams[i];
		struct bt_bap_stream *bap_stream = &cap_stream_active->bap_stream;
		int err;

		/* TODO: Add metadata */
		err = bt_bap_stream_enable(bap_stream,
					     bap_stream->codec->meta,
					     bap_stream->codec->meta_count);
		if (err != 0) {
			LOG_DBG("Failed to enable stream %p: %d",
				cap_stream_active, err);

			/* End or mark procedure as aborted.
			 * If we have sent any requests over air, we will abort
			 * once all sent requests has completed
			 */
			cap_abort_proc(bap_stream->conn, err);
			if (i == 0U) {
				cap_initiator_unicast_audio_proc_complete();
			}

			return;
		}
	}
}

void bt_cap_initiator_enabled(struct bt_cap_stream *cap_stream)
{
	struct bt_bap_stream *bap_stream;
	int err;

	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_ENABLE) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p enabled (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);

		if (!cap_proc_is_done()) {
			/* Not yet finished, wait for all */
			return;
		}
	}

	if (cap_proc_is_aborted()) {
		if (cap_proc_all_streams_handled()) {
			cap_initiator_unicast_audio_proc_complete();
		}

		return;
	}

	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_START);

	bap_stream = &active_proc.streams[0]->bap_stream;

	/* Since bt_bap_stream_start connects the ISO, we can, at this point,
	 * only do this one by one due to a restriction in the ISO layer
	 * (maximum 1 outstanding ISO connection request at any one time).
	 */
	err = bt_bap_stream_start(bap_stream);
	if (err != 0) {
		LOG_DBG("Failed to start stream %p: %d", active_proc.streams[0], err);

		/* End and mark procedure as aborted.
		 * If we have sent any requests over air, we will abort
		 * once all sent requests has completed
		 */
		cap_abort_proc(bap_stream->conn, err);
		cap_initiator_unicast_audio_proc_complete();

		return;
	}
}

void bt_cap_initiator_started(struct bt_cap_stream *cap_stream)
{
	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_START) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p started (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);
	}

	/* Since bt_bap_stream_start connects the ISO, we can, at this point,
	 * only do this one by one due to a restriction in the ISO layer
	 * (maximum 1 outstanding ISO connection request at any one time).
	 */
	if (!cap_proc_is_done()) {
		struct bt_cap_stream *next = active_proc.streams[active_proc.stream_done_cnt];
		struct bt_bap_stream *bap_stream = &next->bap_stream;
		int err;

		/* Not yet finished, start next */
		err = bt_bap_stream_start(bap_stream);
		if (err != 0) {
			LOG_DBG("Failed to start stream %p: %d", next, err);

			/* End and mark procedure as aborted.
			 * If we have sent any requests over air, we will abort
			 * once all sent requests has completed
			 */
			cap_abort_proc(bap_stream->conn, err);
			cap_initiator_unicast_audio_proc_complete();
		}
	} else {
		cap_initiator_unicast_audio_proc_complete();
	}
}

static bool can_update_metadata(const struct bt_bap_stream *bap_stream)
{
	struct bt_bap_ep_info ep_info;
	int err;

	if (bap_stream->conn == NULL) {
		return false;
	}

	err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
	if (err != 0) {
		LOG_DBG("Failed to get endpoint info %p: %d", bap_stream, err);

		return false;
	}

	return ep_info.state == BT_BAP_EP_STATE_ENABLING ||
	       ep_info.state == BT_BAP_EP_STATE_STREAMING;
}

int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param params[],
					  size_t count)
{
	CHECKIF(params == NULL) {
		LOG_DBG("params is NULL");

		return -EINVAL;
	}

	CHECKIF(count == 0) {
		LOG_DBG("count is 0");

		return -EINVAL;
	}

	if (cap_proc_is_active()) {
		LOG_DBG("A CAP procedure is already in progress");

		return -EBUSY;
	}

	for (size_t i = 0U; i < count; i++) {
		CHECKIF(params[i].stream == NULL) {
			LOG_DBG("params[%zu].stream is NULL", i);

			return -EINVAL;
		}

		CHECKIF(params[i].stream->bap_stream.conn == NULL) {
			LOG_DBG("params[%zu].stream->bap_stream.conn is NULL", i);

			return -EINVAL;
		}

		CHECKIF(!cap_initiator_valid_metadata(params[i].meta,
						      params[i].meta_count)) {
			LOG_DBG("params[%zu].meta is invalid", i);

			return -EINVAL;
		}

		for (size_t j = 0U; j < i; j++) {
			if (params[j].stream == params[i].stream) {
				LOG_DBG("param.streams[%zu] is duplicated by param.streams[%zu]",
					j, i);
				return -EINVAL;
			}
		}

		if (!can_update_metadata(&params[i].stream->bap_stream)) {
			LOG_DBG("params[%zu].stream is not in right state to be updated", i);

			return -EINVAL;
		}
	}

	atomic_set_bit(active_proc.proc_state_flags,
		       CAP_UNICAST_PROC_STATE_ACTIVE);
	active_proc.stream_cnt = count;
	active_proc.proc_type = CAP_UNICAST_PROC_TYPE_UPDATE;

	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_META_UPDATE);

	/** TODO: If this is a CSIP set, then the order of the procedures may
	 * not match the order in the parameters, and the CSIP ordered access
	 * procedure should be used.
	 */
	for (size_t i = 0U; i < count; i++) {
		int err;

		active_proc.streams[i] = params[i].stream;

		err = bt_bap_stream_metadata(&params[i].stream->bap_stream, params[i].meta,
					     params[i].meta_count);
		if (err != 0) {
			LOG_DBG("Failed to update metadata for stream %p: %d",
				params[i].stream, err);

			if (i > 0U) {
				cap_abort_proc(params[i].stream->bap_stream.conn, err);
			} else {
				(void)memset(&active_proc, 0,
					     sizeof(active_proc));
			}

			return err;
		}

		active_proc.stream_initiated_cnt++;
	}

	return 0;
}

int bt_cap_initiator_unicast_audio_cancel(void)
{
	if (!cap_proc_is_active() && !cap_proc_is_aborted()) {
		LOG_DBG("No CAP procedure is in progress");

		return -EALREADY;
	}

	cap_abort_proc(NULL, -ECANCELED);
	cap_initiator_unicast_audio_proc_complete();

	return 0;
}

void bt_cap_initiator_metadata_updated(struct bt_cap_stream *cap_stream)
{
	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_META_UPDATE) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p QoS metadata updated (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);
	}

	if (!cap_proc_is_done()) {
		/* Not yet finished, wait for all */
		return;
	} else if (cap_proc_is_aborted()) {
		if (cap_proc_all_streams_handled()) {
			cap_initiator_unicast_audio_proc_complete();
		}

		return;
	}

	cap_initiator_unicast_audio_proc_complete();
}

static bool can_release(const struct bt_bap_stream *bap_stream)
{
	struct bt_bap_ep_info ep_info;
	int err;

	if (bap_stream->conn == NULL) {
		return false;
	}

	err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
	if (err != 0) {
		LOG_DBG("Failed to get endpoint info %p: %d", bap_stream, err);

		return false;
	}

	return ep_info.state != BT_BAP_EP_STATE_IDLE;
}

int bt_cap_initiator_unicast_audio_stop(struct bt_bap_unicast_group *unicast_group)
{
	struct bt_bap_stream *bap_stream;
	size_t stream_cnt;

	if (cap_proc_is_active()) {
		LOG_DBG("A CAP procedure is already in progress");

		return -EBUSY;
	}

	CHECKIF(unicast_group == NULL) {
		LOG_DBG("unicast_group is NULL");
		return -EINVAL;
	}

	stream_cnt = 0U;
	SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, bap_stream, _node) {
		if (can_release(bap_stream)) {
			stream_cnt++;
		}
	}

	if (stream_cnt == 0U) {
		LOG_DBG("All streams are already stopped");

		return -EALREADY;
	}

	atomic_set_bit(active_proc.proc_state_flags,
		       CAP_UNICAST_PROC_STATE_ACTIVE);
	active_proc.stream_cnt = stream_cnt;
	active_proc.unicast_group = unicast_group;
	active_proc.proc_type = CAP_UNICAST_PROC_TYPE_STOP;

	cap_set_subproc(CAP_UNICAST_SUBPROC_TYPE_RELEASE);

	/** TODO: If this is a CSIP set, then the order of the procedures may
	 * not match the order in the parameters, and the CSIP ordered access
	 * procedure should be used.
	 */
	SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, bap_stream, _node) {
		struct bt_cap_stream *cap_stream =
			CONTAINER_OF(bap_stream, struct bt_cap_stream, bap_stream);
		int err;

		if (!can_release(bap_stream)) {
			continue;
		}

		active_proc.streams[active_proc.stream_initiated_cnt] = cap_stream;

		err = bt_bap_stream_release(bap_stream);
		if (err != 0) {
			LOG_DBG("Failed to stop bap_stream %p: %d", bap_stream, err);

			if (active_proc.stream_initiated_cnt > 0U) {
				cap_abort_proc(bap_stream->conn, err);
			} else {
				(void)memset(&active_proc, 0,
					     sizeof(active_proc));
			}

			return err;
		}

		active_proc.stream_initiated_cnt++;
	}

	return 0;
}

void bt_cap_initiator_released(struct bt_cap_stream *cap_stream)
{
	if (!cap_stream_in_active_proc(cap_stream)) {
		/* State change happened outside of a procedure; ignore */
		return;
	}

	if (active_proc.subproc_type != CAP_UNICAST_SUBPROC_TYPE_RELEASE) {
		/* Unexpected callback - Abort */
		cap_abort_proc(cap_stream->bap_stream.conn, -EBADMSG);
	} else {
		active_proc.stream_done_cnt++;

		LOG_DBG("Stream %p released (%zu/%zu streams done)",
			cap_stream, active_proc.stream_done_cnt,
			active_proc.stream_cnt);
	}

	if (!cap_proc_is_done()) {
		/* Not yet finished, wait for all */
		return;
	} else if (cap_proc_is_aborted()) {
		if (cap_proc_all_streams_handled()) {
			cap_initiator_unicast_audio_proc_complete();
		}

		return;
	}

	cap_initiator_unicast_audio_proc_complete();
}

#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */

#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) && defined(CONFIG_BT_BAP_UNICAST_CLIENT)

int bt_cap_initiator_unicast_to_broadcast(
	const struct bt_cap_unicast_to_broadcast_param *param,
	struct bt_cap_broadcast_source **source)
{
	return -ENOSYS;
}

int bt_cap_initiator_broadcast_to_unicast(const struct bt_cap_broadcast_to_unicast_param *param,
					  struct bt_bap_unicast_group **unicast_group)
{
	return -ENOSYS;
}

#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE && CONFIG_BT_BAP_UNICAST_CLIENT */
