/* csip.c - CAP Commander specific VCP mocks */

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

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

static struct bt_vcp_vol_ctlr_cb *vcp_cb;

static struct bt_vcp_vol_ctlr {
	struct bt_conn *conn;
	struct bt_vocs *vocs[CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST];
	struct bt_aics *aics[CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST];
} vol_ctlrs[CONFIG_BT_MAX_CONN];

struct bt_vcp_vol_ctlr *bt_vcp_vol_ctlr_get_by_conn(const struct bt_conn *conn)
{
	for (size_t i = 0; i < ARRAY_SIZE(vol_ctlrs); i++) {
		if (vol_ctlrs[i].conn == conn) {
			return &vol_ctlrs[i];
		}
	}

	return NULL;
}

int bt_vcp_vol_ctlr_conn_get(const struct bt_vcp_vol_ctlr *vol_ctlr, struct bt_conn **conn)
{
	*conn = vol_ctlr->conn;

	return 0;
}

int bt_vcp_vol_ctlr_set_vol(struct bt_vcp_vol_ctlr *vol_ctlr, uint8_t volume)
{
	if (vcp_cb != NULL && vcp_cb->vol_set != NULL) {
		vcp_cb->vol_set(vol_ctlr, 0);
	}

	return 0;
}

int bt_vcp_vol_ctlr_mute(struct bt_vcp_vol_ctlr *vol_ctlr)
{
	if (vcp_cb != NULL && vcp_cb->mute != NULL) {
		vcp_cb->mute(vol_ctlr, 0);
	}

	return 0;
}

int bt_vcp_vol_ctlr_unmute(struct bt_vcp_vol_ctlr *vol_ctlr)
{
	if (vcp_cb != NULL && vcp_cb->unmute != NULL) {
		vcp_cb->unmute(vol_ctlr, 0);
	}

	return 0;
}

int bt_vcp_vol_ctlr_discover(struct bt_conn *conn, struct bt_vcp_vol_ctlr **vol_ctlr)
{
	for (size_t i = 0; i < ARRAY_SIZE(vol_ctlrs); i++) {
		if (vol_ctlrs[i].conn == NULL) {
			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
				const int err = bt_vocs_discover(conn, vol_ctlrs[i].vocs[j], NULL);

				if (err != 0) {
					return err;
				}
			}

			vol_ctlrs[i].conn = conn;
			*vol_ctlr = &vol_ctlrs[i];

			return 0;
		}
	}

	return -ENOMEM;
}

int bt_vcp_vol_ctlr_cb_register(struct bt_vcp_vol_ctlr_cb *cb)
{
	vcp_cb = cb;

	if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR_VOCS)) {
		for (size_t i = 0U; i < ARRAY_SIZE(vol_ctlrs); i++) {
			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
				bt_vocs_client_cb_register(vol_ctlrs[i].vocs[j], &cb->vocs_cb);
			}
		}
	}

	return 0;
}

int bt_vcp_vol_ctlr_included_get(struct bt_vcp_vol_ctlr *vol_ctlr, struct bt_vcp_included *included)
{
	included->vocs_cnt = ARRAY_SIZE(vol_ctlr->vocs);
	included->vocs = vol_ctlr->vocs;

	included->aics_cnt = ARRAY_SIZE(vol_ctlr->aics);
	included->aics = vol_ctlr->aics;

	return 0;
}

void mock_bt_vcp_init(void)
{
	if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR_VOCS)) {
		for (size_t i = 0U; i < ARRAY_SIZE(vol_ctlrs); i++) {
			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
				vol_ctlrs[i].vocs[j] = bt_vocs_client_free_instance_get();

				__ASSERT(vol_ctlrs[i].vocs[j],
					 "Could not allocate VOCS client instance");
			}
		}
	}
}

void mock_bt_vcp_cleanup(void)
{
	memset(vol_ctlrs, 0, sizeof(vol_ctlrs));
}
