/* bap_base.c - BAP BASE handling */

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

#include <zephyr/bluetooth/iso.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/check.h>

LOG_MODULE_REGISTER(bt_bap_base, CONFIG_BT_BAP_BASE_LOG_LEVEL);

/* The BASE and the following defines are defined by BAP v1.0.1, section 3.7.2.2 Basic Audio
 * Announcements
 */
#define BASE_MAX_SIZE            (UINT8_MAX - 1 /* type */ - BT_UUID_SIZE_16)
#define BASE_CODEC_ID_SIZE       (1 /* id */ + 2 /* cid */ + 2 /* vid */)
#define BASE_PD_SIZE             3
#define BASE_SUBGROUP_COUNT_SIZE 1
#define BASE_NUM_BIS_SIZE        1
#define BASE_CC_LEN_SIZE         1
#define BASE_META_LEN_SIZE       1
#define BASE_BIS_INDEX_SIZE      1
#define BASE_BIS_CC_LEN_SIZE     1
#define BASE_SUBGROUP_MAX_SIZE   (BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE)
#define BASE_SUBGROUP_MIN_SIZE                                                                     \
	(BASE_NUM_BIS_SIZE + BASE_CODEC_ID_SIZE + BASE_CC_LEN_SIZE + BASE_META_LEN_SIZE +          \
	 BASE_BIS_INDEX_SIZE + BASE_BIS_CC_LEN_SIZE)
#define BASE_MIN_SIZE                                                                              \
	(BT_UUID_SIZE_16 + BASE_PD_SIZE + BASE_SUBGROUP_COUNT_SIZE + BASE_SUBGROUP_MIN_SIZE)
#define BASE_SUBGROUP_MAX_COUNT                                                                    \
	((BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE) / BASE_SUBGROUP_MIN_SIZE)

static uint32_t base_pull_pd(struct net_buf_simple *net_buf)
{
	return net_buf_simple_pull_le24(net_buf);
}

static uint8_t base_pull_bis_count(struct net_buf_simple *net_buf)
{
	return net_buf_simple_pull_u8(net_buf);
}

static void base_pull_codec_id(struct net_buf_simple *net_buf,
			       struct bt_bap_base_codec_id *codec_id)
{
	struct bt_bap_base_codec_id codec;

	codec.id = net_buf_simple_pull_u8(net_buf);    /* coding format */
	codec.cid = net_buf_simple_pull_le16(net_buf); /* company id */
	codec.vid = net_buf_simple_pull_le16(net_buf); /* VS codec id */

	if (codec_id != NULL) {
		*codec_id = codec;
	}
}

static uint8_t base_pull_ltv(struct net_buf_simple *net_buf, uint8_t **data)
{
	const uint8_t len = net_buf_simple_pull_u8(net_buf);

	if (data == NULL) {
		net_buf_simple_pull_mem(net_buf, len);
	} else {
		*data = net_buf_simple_pull_mem(net_buf, len);
	}

	return len;
}

static bool check_pull_ltv(struct net_buf_simple *net_buf)
{
	uint8_t ltv_len;

	if (net_buf->len < sizeof(ltv_len)) {
		return false;
	}

	ltv_len = net_buf_simple_pull_u8(net_buf);
	if (net_buf->len < ltv_len) {
		return false;
	}
	net_buf_simple_pull_mem(net_buf, ltv_len);

	return true;
}

const struct bt_bap_base *bt_bap_base_get_base_from_ad(const struct bt_data *ad)
{
	struct bt_uuid_16 broadcast_uuid;
	const struct bt_bap_base *base;
	struct net_buf_simple net_buf;
	uint8_t subgroup_count;
	void *uuid;

	CHECKIF(ad == NULL) {
		LOG_DBG("data is NULL");

		return NULL;
	}

	if (ad->type != BT_DATA_SVC_DATA16) {
		LOG_DBG("Invalid type: %u", ad->type);

		return NULL;
	}

	if (ad->data_len < BASE_MIN_SIZE) {
		LOG_DBG("Invalid len: %u", ad->data_len);

		return NULL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)ad->data, ad->data_len);

	uuid = net_buf_simple_pull_mem(&net_buf, BT_UUID_SIZE_16);
	if (!bt_uuid_create(&broadcast_uuid.uuid, uuid, BT_UUID_SIZE_16)) {
		LOG_ERR("bt_uuid_create failed");

		return NULL;
	}

	if (bt_uuid_cmp(&broadcast_uuid.uuid, BT_UUID_BASIC_AUDIO) != 0) {
		LOG_DBG("Invalid UUID");

		return NULL;
	}

	/* Store the start of the BASE */
	base = (const struct bt_bap_base *)net_buf.data;

	/* Pull all data to verify that the result BASE is valid */
	base_pull_pd(&net_buf);
	subgroup_count = net_buf_simple_pull_u8(&net_buf);
	if (subgroup_count == 0 || subgroup_count > BASE_SUBGROUP_MAX_COUNT) {
		LOG_DBG("Invalid subgroup count: %u", subgroup_count);

		return NULL;
	}

	for (uint8_t i = 0U; i < subgroup_count; i++) {
		uint8_t bis_count;

		if (net_buf.len < sizeof(bis_count)) {
			LOG_DBG("Invalid BASE length: %u", ad->data_len);

			return NULL;
		}

		bis_count = base_pull_bis_count(&net_buf);
		if (bis_count == 0 || bis_count > BT_ISO_MAX_GROUP_ISO_COUNT) {
			LOG_DBG("Subgroup[%u]: Invalid BIS count: %u", i, bis_count);

			return NULL;
		}

		if (net_buf.len < BASE_CODEC_ID_SIZE) {
			LOG_DBG("Invalid BASE length: %u", ad->data_len);

			return NULL;
		}

		base_pull_codec_id(&net_buf, NULL);

		/* Pull CC */
		if (!check_pull_ltv(&net_buf)) {
			LOG_DBG("Invalid BASE length: %u", ad->data_len);

			return NULL;
		}

		/* Pull meta */
		if (!check_pull_ltv(&net_buf)) {
			LOG_DBG("Invalid BASE length: %u", ad->data_len);

			return NULL;
		}

		for (uint8_t j = 0U; j < bis_count; j++) {
			uint8_t bis_index;

			if (net_buf.len < sizeof(bis_index)) {
				LOG_DBG("Invalid BASE length: %u", ad->data_len);

				return NULL;
			}

			bis_index = net_buf_simple_pull_u8(&net_buf);
			if (bis_index == 0 || bis_index > BT_ISO_BIS_INDEX_MAX) {
				LOG_DBG("Subgroup[%u]: Invalid BIS index: %u", i, bis_index);

				return NULL;
			}

			/* Pull BIS CC data */
			if (!check_pull_ltv(&net_buf)) {
				LOG_DBG("Invalid BASE length: %u", ad->data_len);

				return NULL;
			}
		}
	}

	return base;
}

int bt_bap_base_get_pres_delay(const struct bt_bap_base *base)
{
	struct net_buf_simple net_buf;
	uint32_t pd;

	CHECKIF(base == NULL) {
		LOG_DBG("base is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)base, sizeof(pd));
	pd = base_pull_pd(&net_buf);

	return (int)pd; /* PD is 24-bit so it fits in an int */
}

int bt_bap_base_get_subgroup_count(const struct bt_bap_base *base)
{
	struct net_buf_simple net_buf;
	uint8_t subgroup_count;

	CHECKIF(base == NULL) {
		LOG_DBG("base is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)base, BASE_MAX_SIZE);
	base_pull_pd(&net_buf);
	subgroup_count = net_buf_simple_pull_u8(&net_buf);

	return (int)subgroup_count; /* subgroup_count is 8-bit so it fits in an int */
}

int bt_bap_base_foreach_subgroup(const struct bt_bap_base *base,
				 bool (*func)(const struct bt_bap_base_subgroup *data,
					      void *user_data),
				 void *user_data)
{
	struct bt_bap_base_subgroup *subgroup;
	struct net_buf_simple net_buf;
	uint8_t subgroup_count;

	CHECKIF(base == NULL) {
		LOG_DBG("base is NULL");

		return -EINVAL;
	}

	CHECKIF(func == NULL) {
		LOG_DBG("func is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)base, BASE_MAX_SIZE);
	base_pull_pd(&net_buf);
	subgroup_count = net_buf_simple_pull_u8(&net_buf);

	for (uint8_t i = 0U; i < subgroup_count; i++) {
		subgroup = (struct bt_bap_base_subgroup *)net_buf.data;
		if (!func(subgroup, user_data)) {
			LOG_DBG("user stopped parsing");

			return -ECANCELED;
		}

		/* Parse subgroup data to get next subgroup pointer */
		if (subgroup_count > 1) { /* Only parse data if it isn't the last one */
			uint8_t bis_count;

			bis_count = base_pull_bis_count(&net_buf);
			base_pull_codec_id(&net_buf, NULL);

			/* Codec config */
			base_pull_ltv(&net_buf, NULL);

			/* meta */
			base_pull_ltv(&net_buf, NULL);

			for (uint8_t j = 0U; j < bis_count; j++) {
				net_buf_simple_pull_u8(&net_buf); /* index */

				/* Codec config */
				base_pull_ltv(&net_buf, NULL);
			}
		}
	}

	return 0;
}

int bt_bap_base_get_subgroup_codec_id(const struct bt_bap_base_subgroup *subgroup,
				      struct bt_bap_base_codec_id *codec_id)
{
	struct net_buf_simple net_buf;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	CHECKIF(codec_id == NULL) {
		LOG_DBG("codec_id is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);
	base_pull_bis_count(&net_buf);
	base_pull_codec_id(&net_buf, codec_id);

	return 0;
}

int bt_bap_base_get_subgroup_codec_data(const struct bt_bap_base_subgroup *subgroup, uint8_t **data)
{
	struct net_buf_simple net_buf;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	CHECKIF(data == NULL) {
		LOG_DBG("data is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);
	base_pull_bis_count(&net_buf);
	base_pull_codec_id(&net_buf, NULL);

	/* Codec config */
	return base_pull_ltv(&net_buf, data);
}

int bt_bap_base_get_subgroup_codec_meta(const struct bt_bap_base_subgroup *subgroup, uint8_t **meta)
{
	struct net_buf_simple net_buf;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	CHECKIF(meta == NULL) {
		LOG_DBG("meta is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);
	base_pull_bis_count(&net_buf);
	base_pull_codec_id(&net_buf, NULL);

	/* Codec config */
	base_pull_ltv(&net_buf, NULL);

	/* meta */
	return base_pull_ltv(&net_buf, meta);
}

int bt_bap_base_subgroup_codec_to_codec_cfg(const struct bt_bap_base_subgroup *subgroup,
					    struct bt_audio_codec_cfg *codec_cfg)
{
	struct bt_bap_base_codec_id codec_id;
	struct net_buf_simple net_buf;
	uint8_t *ltv_data;
	uint8_t ltv_len;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	CHECKIF(codec_cfg == NULL) {
		LOG_DBG("codec_cfg is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);
	base_pull_bis_count(&net_buf);
	base_pull_codec_id(&net_buf, &codec_id);

	codec_cfg->id = codec_id.id;
	codec_cfg->cid = codec_id.cid;
	codec_cfg->vid = codec_id.vid;

	/* Codec config */
	ltv_len = base_pull_ltv(&net_buf, &ltv_data);

	if (ltv_len > ARRAY_SIZE(codec_cfg->data)) {
		LOG_DBG("Cannot fit %u octets of codec data (max %zu)", ltv_len,
			ARRAY_SIZE(codec_cfg->data));

		return -ENOMEM;
	}

	codec_cfg->data_len = ltv_len;
	memcpy(codec_cfg->data, ltv_data, ltv_len);

	/* Meta */
	ltv_len = base_pull_ltv(&net_buf, &ltv_data);

	if (ltv_len > ARRAY_SIZE(codec_cfg->meta)) {
		LOG_DBG("Cannot fit %u octets of codec meta (max %zu)", ltv_len,
			ARRAY_SIZE(codec_cfg->meta));

		return -ENOMEM;
	}

	codec_cfg->meta_len = ltv_len;
	memcpy(codec_cfg->meta, ltv_data, ltv_len);

	return 0;
}
int bt_bap_base_get_subgroup_bis_count(const struct bt_bap_base_subgroup *subgroup)
{
	struct net_buf_simple net_buf;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);

	return base_pull_bis_count(&net_buf);
}

int bt_bap_base_subgroup_foreach_bis(const struct bt_bap_base_subgroup *subgroup,
				     bool (*func)(const struct bt_bap_base_subgroup_bis *subgroup,
						  void *user_data),
				     void *user_data)
{
	struct net_buf_simple net_buf;
	uint8_t bis_count;

	CHECKIF(subgroup == NULL) {
		LOG_DBG("subgroup is NULL");

		return -EINVAL;
	}

	CHECKIF(func == NULL) {
		LOG_DBG("func is NULL");

		return -EINVAL;
	}

	net_buf_simple_init_with_data(&net_buf, (void *)subgroup, BASE_SUBGROUP_MAX_SIZE);

	bis_count = base_pull_bis_count(&net_buf);
	base_pull_codec_id(&net_buf, NULL);

	/* Codec config */
	base_pull_ltv(&net_buf, NULL);

	/* meta */
	base_pull_ltv(&net_buf, NULL);

	for (uint8_t i = 0U; i < bis_count; i++) {
		struct bt_bap_base_subgroup_bis bis;

		bis.index = net_buf_simple_pull_u8(&net_buf); /* index */

		/* Codec config */
		bis.data_len = base_pull_ltv(&net_buf, &bis.data);

		if (!func(&bis, user_data)) {
			LOG_DBG("user stopped parsing");

			return -ECANCELED;
		}
	}

	return 0;
}

int bt_bap_base_subgroup_bis_codec_to_codec_cfg(const struct bt_bap_base_subgroup_bis *bis,
						struct bt_audio_codec_cfg *codec_cfg)
{
	CHECKIF(bis == NULL) {
		LOG_DBG("bis is NULL");

		return -EINVAL;
	}

	CHECKIF(codec_cfg == NULL) {
		LOG_DBG("codec_cfg is NULL");

		return -EINVAL;
	}

	if (bis->data_len > ARRAY_SIZE(codec_cfg->data)) {
		LOG_DBG("Cannot fit %u octets of codec data (max %zu)", bis->data_len,
			ARRAY_SIZE(codec_cfg->data));

		return -ENOMEM;
	}

	codec_cfg->data_len = bis->data_len;
	memcpy(codec_cfg->data, bis->data, bis->data_len);

	return 0;
}

static bool base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis, void *user_data)
{
	uint32_t *base_bis_index_bitfield = user_data;

	*base_bis_index_bitfield |= BIT(bis->index);

	return true;
}

static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
{
	const int err = bt_bap_base_subgroup_foreach_bis(subgroup, base_subgroup_bis_cb, user_data);

	if (err != 0) {
		LOG_DBG("Failed to parse all BIS: %d", err);
		return false;
	}

	return true;
}

int bt_bap_base_get_bis_indexes(const struct bt_bap_base *base, uint32_t *bis_indexes)
{
	CHECKIF(base == NULL) {
		LOG_DBG("base is NULL");

		return -EINVAL;
	}

	CHECKIF(bis_indexes == NULL) {
		LOG_DBG("bis_indexes is NULL");

		return -EINVAL;
	}

	*bis_indexes = 0U;

	return bt_bap_base_foreach_subgroup(base, base_subgroup_cb, bis_indexes);
}
