/*
 * 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_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_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_start_complete(void)
{
	struct bt_bap_unicast_group *unicast_group;
	struct bt_conn *failed_conn;
	int err;

	/* 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;
	failed_conn = active_proc.failed_conn;
	err = active_proc.err;

	(void)memset(&active_proc, 0, sizeof(active_proc));
	if (cap_cb != NULL && cap_cb->unicast_start_complete != NULL) {
		cap_cb->unicast_start_complete(unicast_group, err, failed_conn);
	}
}

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;

	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_start_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_start_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_start_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_start_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_start_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_start_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_start_complete();
		}
	} else {
		cap_initiator_unicast_audio_start_complete();
	}
}

static void cap_initiator_unicast_audio_update_complete(void)
{
	struct bt_conn *failed_conn;
	int err;

	failed_conn = active_proc.failed_conn;
	err = active_proc.err;

	(void)memset(&active_proc, 0, sizeof(active_proc));
	if (cap_cb != NULL && cap_cb->unicast_update_complete != NULL) {
		cap_cb->unicast_update_complete(err, failed_conn);
	}
}

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;

	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;
}

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_update_complete();
		}

		return;
	}

	cap_initiator_unicast_audio_update_complete();
}

static void cap_initiator_unicast_audio_stop_complete(void)
{
	struct bt_bap_unicast_group *unicast_group;
	struct bt_conn *failed_conn;
	int err;

	unicast_group = active_proc.unicast_group;
	failed_conn = active_proc.failed_conn;
	err = active_proc.err;

	(void)memset(&active_proc, 0, sizeof(active_proc));

	if (cap_cb != NULL && cap_cb->unicast_stop_complete != NULL) {
		cap_cb->unicast_stop_complete(unicast_group, err, failed_conn);
	}
}

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;

	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_stop_complete();
		}

		return;
	}

	cap_initiator_unicast_audio_stop_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 */
