/* bap_iso.c - BAP ISO handling */

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

#include "bap_iso.h"
#include "audio_internal.h"
#include "bap_endpoint.h"

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_bap_iso, CONFIG_BT_BAP_ISO_LOG_LEVEL);

/* TODO: Optimize the ISO_POOL_SIZE */
#define ISO_POOL_SIZE CONFIG_BT_ISO_MAX_CHAN

static struct bt_bap_iso iso_pool[ISO_POOL_SIZE];

struct bt_bap_iso *bt_bap_iso_new(void)
{
	struct bt_bap_iso *iso = NULL;

	for (size_t i = 0; i < ARRAY_SIZE(iso_pool); i++) {
		if (atomic_cas(&iso_pool[i].ref, 0, 1)) {
			iso = &iso_pool[i];
			break;
		}
	}

	if (!iso) {
		return NULL;
	}

	(void)memset(iso, 0, offsetof(struct bt_bap_iso, ref));

	return iso;
}

struct bt_bap_iso *bt_bap_iso_ref(struct bt_bap_iso *iso)
{
	atomic_val_t old;

	__ASSERT_NO_MSG(iso != NULL);

	/* Reference counter must be checked to avoid incrementing ref from
	 * zero, then we should return NULL instead.
	 * Loop on clear-and-set in case someone has modified the reference
	 * count since the read, and start over again when that happens.
	 */
	do {
		old = atomic_get(&iso->ref);

		if (!old) {
			return NULL;
		}
	} while (!atomic_cas(&iso->ref, old, old + 1));

	return iso;
}

void bt_bap_iso_unref(struct bt_bap_iso *iso)
{
	atomic_val_t old;

	__ASSERT_NO_MSG(iso != NULL);

	old = atomic_dec(&iso->ref);

	__ASSERT(old > 0, "iso reference counter is 0");
}

void bt_bap_iso_foreach(bt_bap_iso_func_t func, void *user_data)
{
	for (size_t i = 0; i < ARRAY_SIZE(iso_pool); i++) {
		struct bt_bap_iso *iso = bt_bap_iso_ref(&iso_pool[i]);
		bool iter;

		if (!iso) {
			continue;
		}

		iter = func(iso, user_data);
		bt_bap_iso_unref(iso);

		if (!iter) {
			return;
		}
	}
}

struct bt_bap_iso_find_param {
	struct bt_bap_iso *iso;
	bt_bap_iso_func_t func;
	void *user_data;
};

static bool bt_bap_iso_find_cb(struct bt_bap_iso *iso, void *user_data)
{
	struct bt_bap_iso_find_param *param = user_data;
	bool found;

	found = param->func(iso, param->user_data);
	if (found) {
		param->iso = bt_bap_iso_ref(iso);
	}

	return !found;
}

struct bt_bap_iso *bt_bap_iso_find(bt_bap_iso_func_t func, void *user_data)
{
	struct bt_bap_iso_find_param param = {
		.iso = NULL,
		.func = func,
		.user_data = user_data,
	};

	bt_bap_iso_foreach(bt_bap_iso_find_cb, &param);

	return param.iso;
}

void bt_bap_iso_init(struct bt_bap_iso *iso, struct bt_iso_chan_ops *ops)
{
	iso->chan.ops = ops;
	iso->chan.qos = &iso->qos;

	/* Setup points for both Tx and Rx
	 * This is due to the limitation in the ISO API where pointers like
	 * the `qos->tx` shall be initialized before the CIS is connected if
	 * ever want to use it for TX, and ditto for RX. They cannot be
	 * initialized after the CIS has been connected
	 */
	iso->chan.qos->rx = &iso->rx.qos;
	iso->chan.qos->rx->path = &iso->rx.path;
	iso->chan.qos->rx->path->cc = iso->rx.cc;

	iso->chan.qos->tx = &iso->tx.qos;
	iso->chan.qos->tx->path = &iso->tx.path;
	iso->chan.qos->tx->path->cc = iso->tx.cc;
}

static struct bt_bap_iso_dir *bap_iso_get_iso_dir(bool unicast_client, struct bt_bap_iso *iso,
						  enum bt_audio_dir dir)
{
	/* TODO FIX FOR CLIENT */
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && unicast_client) {
		/* For the unicast client, the direction and tx/rx is reversed */
		if (dir == BT_AUDIO_DIR_SOURCE) {
			return &iso->rx;
		} else {
			return &iso->tx;
		}
	}

	if (dir == BT_AUDIO_DIR_SINK) {
		return &iso->rx;
	} else {
		return &iso->tx;
	}
}

static bool is_unicast_client_ep(struct bt_bap_ep *ep)
{
	return IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && bt_bap_ep_is_unicast_client(ep);
}

void bt_bap_iso_bind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep)
{
	struct bt_bap_iso_dir *iso_dir;

	__ASSERT_NO_MSG(ep != NULL);
	__ASSERT_NO_MSG(iso != NULL);
	__ASSERT(ep->iso == NULL, "ep %p bound with iso %p already", ep, ep->iso);
	__ASSERT(ep->dir == BT_AUDIO_DIR_SINK || ep->dir == BT_AUDIO_DIR_SOURCE,
		 "invalid dir: %u", ep->dir);

	LOG_DBG("iso %p ep %p dir %s", iso, ep, bt_audio_dir_str(ep->dir));

	iso_dir = bap_iso_get_iso_dir(is_unicast_client_ep(ep), iso, ep->dir);
	__ASSERT(iso_dir->ep == NULL, "iso %p bound with ep %p", iso, iso_dir);
	iso_dir->ep = ep;

	ep->iso = bt_bap_iso_ref(iso);
}

void bt_bap_iso_unbind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep)
{
	struct bt_bap_iso_dir *iso_dir;

	__ASSERT_NO_MSG(ep != NULL);
	__ASSERT_NO_MSG(iso != NULL);
	__ASSERT(ep->iso == iso, "ep %p not bound with iso %p, was bound to %p",
		 ep, iso, ep->iso);
	__ASSERT(ep->dir == BT_AUDIO_DIR_SINK || ep->dir == BT_AUDIO_DIR_SOURCE,
		 "Invalid dir: %u", ep->dir);

	LOG_DBG("iso %p ep %p dir %s", iso, ep, bt_audio_dir_str(ep->dir));

	iso_dir = bap_iso_get_iso_dir(is_unicast_client_ep(ep), iso, ep->dir);
	__ASSERT(iso_dir->ep == ep, "iso %p not bound with ep %p", iso, ep);
	iso_dir->ep = NULL;

	bt_bap_iso_unref(ep->iso);
	ep->iso = NULL;
}

struct bt_bap_ep *bt_bap_iso_get_ep(bool unicast_client, struct bt_bap_iso *iso,
				    enum bt_audio_dir dir)
{
	struct bt_bap_iso_dir *iso_dir;

	__ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE,
		 "invalid dir: %u", dir);

	LOG_DBG("iso %p dir %s", iso, bt_audio_dir_str(dir));

	iso_dir = bap_iso_get_iso_dir(unicast_client, iso, dir);

	return iso_dir->ep;
}

struct bt_bap_ep *bt_bap_iso_get_paired_ep(const struct bt_bap_ep *ep)
{
	if (ep->iso->rx.ep == ep) {
		return ep->iso->tx.ep;
	} else {
		return ep->iso->rx.ep;
	}
}

#if defined(CONFIG_BT_BAP_UNICAST_CLIENT)
void bt_bap_iso_bind_stream(struct bt_bap_iso *bap_iso, struct bt_bap_stream *stream)
{
	struct bt_bap_iso_dir *bap_iso_ep;

	__ASSERT_NO_MSG(stream != NULL);
	__ASSERT_NO_MSG(bap_iso != NULL);
	__ASSERT(stream->bap_iso == NULL, "stream %p bound with bap_iso %p already", stream,
		 stream->bap_iso);

	LOG_DBG("bap_iso %p stream %p dir %s", bap_iso, stream, bt_audio_dir_str(stream->dir));

	/* For the unicast client, the direction and tx/rx is reversed */
	if (stream->dir == BT_AUDIO_DIR_SOURCE) {
		bap_iso_ep = &bap_iso->rx;
	} else {
		bap_iso_ep = &bap_iso->tx;
	}

	__ASSERT(bap_iso_ep->stream == NULL, "bap_iso %p bound with stream %p", bap_iso,
		 bap_iso_ep->stream);
	bap_iso_ep->stream = stream;

	stream->bap_iso = bt_bap_iso_ref(bap_iso);
}

void bt_bap_iso_unbind_stream(struct bt_bap_iso *bap_iso, struct bt_bap_stream *stream)
{
	struct bt_bap_iso_dir *bap_iso_ep;

	__ASSERT_NO_MSG(stream != NULL);
	__ASSERT_NO_MSG(bap_iso != NULL);
	__ASSERT(stream->bap_iso != NULL, "stream %p not bound with an bap_iso", stream);

	LOG_DBG("bap_iso %p stream %p dir %s", bap_iso, stream, bt_audio_dir_str(stream->dir));

	/* For the unicast client, the direction and tx/rx is reversed */
	if (stream->dir == BT_AUDIO_DIR_SOURCE) {
		bap_iso_ep = &bap_iso->rx;
	} else {
		bap_iso_ep = &bap_iso->tx;
	}

	__ASSERT(bap_iso_ep->stream == stream, "bap_iso %p (%p) not bound with stream %p (%p)",
		 bap_iso, bap_iso_ep->stream, stream, stream->bap_iso);
	bap_iso_ep->stream = NULL;

	bt_bap_iso_unref(bap_iso);
	stream->bap_iso = NULL;
}

struct bt_bap_stream *bt_bap_iso_get_stream(struct bt_bap_iso *iso, enum bt_audio_dir dir)
{
	__ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE,
		 "invalid dir: %u", dir);

	LOG_DBG("iso %p dir %s", iso, bt_audio_dir_str(dir));

	/* For the unicast client, the direction and tx/rx is reversed */
	if (dir == BT_AUDIO_DIR_SOURCE) {
		return iso->rx.stream;
	} else {
		return iso->tx.stream;
	}
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
