/* main.c - Application main entry point */

/*
 * Copyright (c) 2020 Demant
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <stddef.h>
#include <ztest.h>

#include <bluetooth/hci.h>
#include <sys/byteorder.h>

#define NUM_STD_CODECS 3
static const struct bt_hci_std_codec_info_v2 std_codecs[NUM_STD_CODECS] = {
	{ BT_HCI_CODING_FORMAT_ALAW_LOG,
	  (BT_HCI_CODEC_TRANSPORT_MASK_BREDR_ACL |
	   BT_HCI_CODEC_TRANSPORT_MASK_BREDR_SCO) },
	{ BT_HCI_CODING_FORMAT_TRANSPARENT,
	  BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS },
	{ BT_HCI_CODING_FORMAT_LINEAR_PCM,
	  BT_HCI_CODEC_TRANSPORT_MASK_LE_BIS },
};

#define NUM_VS_CODECS 2
static const struct bt_hci_vs_codec_info_v2 vs_codecs[NUM_VS_CODECS] = {
	{ BT_COMP_ID_LF, 23,
	  BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS },
	{ BT_COMP_ID_LF, 42,
	  (BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS |
	   BT_HCI_CODEC_TRANSPORT_MASK_LE_BIS) },
};


uint8_t hci_vendor_read_std_codecs(
	const struct bt_hci_std_codec_info_v2 **codecs)
{
	*codecs = std_codecs;
	return NUM_STD_CODECS;
}

uint8_t hci_vendor_read_vs_codecs(
	const struct bt_hci_vs_codec_info_v2 **codecs)
{
	*codecs = vs_codecs;
	return NUM_VS_CODECS;
}

void test_read_codecs(void)
{
	const struct bt_hci_rp_read_codecs *codecs;
	struct net_buf *rsp;
	uint8_t num_std_codecs;
	uint8_t num_vs_codecs;
	const uint8_t *ptr;
	uint8_t i;
	int err;

	/* Initialize bluetooth subsystem */
	bt_enable(NULL);

	/* Read Local Supported Codecs */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODECS, NULL, &rsp);
	zassert_equal(err, 0, "Reading local supported codecs failed");

	/* Check returned data */
	codecs = (struct bt_hci_rp_read_codecs *)rsp->data;
	zassert_equal(codecs->status, 0,
		      "Reading local supported codecs status failed");

	ptr = (uint8_t *)&codecs->status + sizeof(codecs->status);
	num_std_codecs = *ptr++;
	zassert_equal(num_std_codecs, NUM_STD_CODECS,
		      "Reading std codecs count failed");

	for (i = 0; i < num_std_codecs; i++) {
		const struct bt_hci_std_codec_info *codec;

		codec = (const struct bt_hci_std_codec_info *)ptr;
		ptr += sizeof(*codec);
		zassert_equal(codec->codec_id, std_codecs[i].codec_id,
			      "Reading std codecs codec_id %d failed", i);
	}

	num_vs_codecs = *ptr++;
	zassert_equal(num_vs_codecs, NUM_VS_CODECS,
		      "Reading vendor codecs count failed");
	for (i = 0; i < num_vs_codecs; i++) {
		const struct bt_hci_vs_codec_info *codec;

		codec = (const struct bt_hci_vs_codec_info *)ptr;
		ptr += sizeof(*codec);
		zassert_equal(codec->company_id,
			      sys_cpu_to_le16(vs_codecs[i].company_id),
			      "Reading vendor codecs company_id %d failed", i);
		zassert_equal(codec->codec_id,
			      sys_cpu_to_le16(vs_codecs[i].codec_id),
			      "Reading vendor codecs codec_id %d failed", i);
	}

	net_buf_unref(rsp);
}

void test_read_codecs_v2(void)
{
	const struct bt_hci_rp_read_codecs_v2 *codecs;
	struct net_buf *rsp;
	uint8_t num_std_codecs;
	uint8_t num_vs_codecs;
	const uint8_t *ptr;
	uint8_t i;
	int err;

	/* Initialize bluetooth subsystem */
	bt_enable(NULL);

	/* Read Local Supported Codecs */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODECS_V2, NULL, &rsp);
	zassert_equal(err, 0, "Reading local supported codecs v2 failed");

	/* Check returned data */
	codecs = (const struct bt_hci_rp_read_codecs_v2 *)rsp->data;
	zassert_equal(codecs->status, 0,
		      "Reading local supported codecs v2 status failed");

	ptr = (uint8_t *)&codecs->status + sizeof(codecs->status);
	num_std_codecs = *ptr++;
	zassert_equal(num_std_codecs, NUM_STD_CODECS,
		      "Reading std codecs count failed");

	for (i = 0; i < num_std_codecs; i++) {
		const struct bt_hci_std_codec_info_v2 *codec;

		codec = (const struct bt_hci_std_codec_info_v2 *)ptr;
		ptr += sizeof(*codec);
		zassert_equal(codec->codec_id, std_codecs[i].codec_id,
			      "Reading std codecs codec_id %d failed", i);
		zassert_equal(codec->transports, std_codecs[i].transports,
			      "Reading std codecs transports %d failed", i);
	}

	num_vs_codecs = *ptr++;
	zassert_equal(num_vs_codecs, NUM_VS_CODECS,
		      "Reading vendor codecs count failed");
	for (i = 0; i < num_vs_codecs; i++) {
		const struct bt_hci_vs_codec_info_v2 *codec;

		codec = (const struct bt_hci_vs_codec_info_v2 *)ptr;
		ptr += sizeof(*codec);
		zassert_equal(codec->company_id,
			      sys_cpu_to_le16(vs_codecs[i].company_id),
			      "Reading vendor codecs company_id %d failed", i);
		zassert_equal(codec->codec_id,
			      sys_cpu_to_le16(vs_codecs[i].codec_id),
			      "Reading vendor codecs codec_id %d failed", i);
		zassert_equal(codec->transports, vs_codecs[i].transports,
			      "Reading vendor codecs transports %d failed", i);
	}

	net_buf_unref(rsp);
}

#define NUM_CAPABILITIES 2
#define CODEC_CAPAB_0 'Z', 'e', 'p', 'h', 'y', 'r'
#define CODEC_CAPAB_1 'C', 'o', 'd', 'e', 'c'
static const uint8_t codec_capabilities[] = {
	sizeof((uint8_t []){CODEC_CAPAB_0}), CODEC_CAPAB_0,
	sizeof((uint8_t []){CODEC_CAPAB_1}), CODEC_CAPAB_1,
};

#define READ_CAPABS_CODING_FMT 0xff
#define READ_CAPABS_COMPANY_ID 0x1234
#define READ_CAPABS_VS_CODEC_ID 0x5678
#define READ_CAPABS_TRANSPORT BT_HCI_LOGICAL_TRANSPORT_TYPE_LE_CIS
#define READ_CAPABS_DIRECTION BT_HCI_DATAPATH_DIR_CTLR_TO_HOST

uint8_t hci_vendor_read_codec_capabilities(uint8_t coding_format,
					   uint16_t company_id,
					   uint16_t vs_codec_id,
					   uint8_t transport,
					   uint8_t direction,
					   uint8_t *num_capabilities,
					   size_t *capabilities_bytes,
					   const uint8_t **capabilities)
{
	/* Check input parameters */
	zassert_equal(coding_format, READ_CAPABS_CODING_FMT,
		      "Reading codec capabilities passed wrong coding_format");
	zassert_equal(company_id, READ_CAPABS_COMPANY_ID,
		      "Reading codec capabilities passed wrong company_id");
	zassert_equal(vs_codec_id, READ_CAPABS_VS_CODEC_ID,
		      "Reading codec capabilities passed wrong vs_codec_id");
	zassert_equal(transport, READ_CAPABS_TRANSPORT,
		      "Reading codec capabilities passed wrong transport");
	zassert_equal(direction, READ_CAPABS_DIRECTION,
		      "Reading codec capabilities passed wrong direction");

	/* Fill in response data */
	*num_capabilities = NUM_CAPABILITIES;
	*capabilities_bytes = sizeof(codec_capabilities);
	*capabilities = codec_capabilities;

	return 0;
}

void test_read_codec_capabilities(void)
{
	struct bt_hci_cp_read_codec_capabilities *cp;
	struct bt_hci_rp_read_codec_capabilities *rp;
	struct net_buf *buf;
	struct net_buf *rsp;
	const uint8_t *ptr;
	int err;

	/* Initialize bluetooth subsystem */
	bt_enable(NULL);

	/* Read Local Supported Codec Capabilities */
	buf = bt_hci_cmd_create(BT_HCI_OP_READ_CODEC_CAPABILITIES, sizeof(*cp));
	cp = net_buf_add(buf, sizeof(*cp));

	cp->codec_id.coding_format = READ_CAPABS_CODING_FMT;
	cp->codec_id.company_id = sys_cpu_to_le16(READ_CAPABS_COMPANY_ID);
	cp->codec_id.vs_codec_id = sys_cpu_to_le16(READ_CAPABS_VS_CODEC_ID);
	cp->transport = READ_CAPABS_TRANSPORT;
	cp->direction = READ_CAPABS_DIRECTION;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODEC_CAPABILITIES,
				   buf, &rsp);
	zassert_equal(err, 0,
		      "Reading local supported codec capabilities failed");

	/* Check returned data */
	rp = (struct bt_hci_rp_read_codec_capabilities *)rsp->data;
	zassert_equal(rp->status, 0,
		      "Reading codec capabilities status failed");
	zassert_equal(rp->num_capabilities, NUM_CAPABILITIES,
		      "Reading codec capabilities count failed");
	ptr = &rp->capabilities[0];
	zassert_mem_equal(ptr, codec_capabilities, sizeof(codec_capabilities),
			  0, "Reading codec capabilities content failed");
}

#define READ_DELAY_CODING_FMT 0xff
#define READ_DELAY_COMPANY_ID 0x9abc
#define READ_DELAY_VS_CODEC_ID 0xdef0
#define READ_DELAY_TRANSPORT BT_HCI_LOGICAL_TRANSPORT_TYPE_LE_BIS
#define READ_DELAY_DIRECTION BT_HCI_DATAPATH_DIR_HOST_TO_CTLR
const uint8_t read_delay_codec_config[] = { 17, 23, 42, 18, 86 };

#define MIN_CTLR_DELAY 0x12
#define MAX_CTLR_DELAY 0x3456

uint8_t hci_vendor_read_ctlr_delay(uint8_t coding_format,
				   uint16_t company_id,
				   uint16_t vs_codec_id,
				   uint8_t transport,
				   uint8_t direction,
				   uint8_t codec_config_len,
				   const uint8_t *codec_config,
				   uint32_t *min_delay,
				   uint32_t *max_delay)
{
	/* Check input parameters */
	zassert_equal(coding_format, READ_DELAY_CODING_FMT,
		      "Reading controller delay passed wrong coding_format");
	zassert_equal(company_id, READ_DELAY_COMPANY_ID,
		      "Reading controller delay passed wrong company_id");
	zassert_equal(vs_codec_id, READ_DELAY_VS_CODEC_ID,
		      "Reading controller delay passed wrong vs_codec_id");
	zassert_equal(transport, READ_DELAY_TRANSPORT,
		      "Reading controller delay passed wrong transport");
	zassert_equal(direction, READ_DELAY_DIRECTION,
		      "Reading controller delay passed wrong direction");
	zassert_equal(codec_config_len, sizeof(read_delay_codec_config),
		      "Reading controller delay passed wrong config length");
	zassert_equal(memcmp(codec_config, read_delay_codec_config,
			     codec_config_len), 0,
		      "Reading controller delay passed wrong config data");

	/* Fill in response data */
	*min_delay = MIN_CTLR_DELAY;
	*max_delay = MAX_CTLR_DELAY;

	return 0;
}

void test_read_ctlr_delay(void)
{
	struct bt_hci_cp_read_ctlr_delay *cp;
	struct bt_hci_rp_read_ctlr_delay *rp;
	struct net_buf *buf;
	struct net_buf *rsp;
	int err;

	/* Initialize bluetooth subsystem */
	bt_enable(NULL);

	/* Read Local Supported Controller Delay */
	buf = bt_hci_cmd_create(BT_HCI_OP_READ_CTLR_DELAY, sizeof(*cp));
	cp = net_buf_add(buf, sizeof(*cp) + sizeof(read_delay_codec_config));

	cp->codec_id.coding_format = READ_DELAY_CODING_FMT;
	cp->codec_id.company_id = sys_cpu_to_le16(READ_DELAY_COMPANY_ID);
	cp->codec_id.vs_codec_id = sys_cpu_to_le16(READ_DELAY_VS_CODEC_ID);
	cp->transport = READ_DELAY_TRANSPORT;
	cp->direction = READ_DELAY_DIRECTION;
	cp->codec_config_len = sizeof(read_delay_codec_config);
	memcpy(cp->codec_config, read_delay_codec_config,
	       sizeof(read_delay_codec_config));

	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CTLR_DELAY, buf, &rsp);
	zassert_equal(err, 0,
		      "Reading local supported controller delay failed");

	/* Check returned data */
	rp = (struct bt_hci_rp_read_ctlr_delay *)rsp->data;
	zassert_equal(rp->status, 0,
		      "Reading controller delay status failed");
	zassert_equal(sys_get_le24(rp->min_ctlr_delay), MIN_CTLR_DELAY,
		      "Reading controller min delay failed");
	zassert_equal(sys_get_le24(rp->max_ctlr_delay), MAX_CTLR_DELAY,
		      "Reading controller max delay failed");
}


/*test case main entry*/
void test_main(void)
{
	ztest_test_suite(test_hci_codecs_info,
			 ztest_unit_test(test_read_codecs),
			 ztest_unit_test(test_read_codecs_v2),
			 ztest_unit_test(test_read_codec_capabilities),
			 ztest_unit_test(test_read_ctlr_delay));
	ztest_run_test_suite(test_hci_codecs_info);
}
