/* 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_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));
}
