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

#include <ctype.h>
#include <stdlib.h>
#include <console/console.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/iso.h>
#include <sys/byteorder.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(iso_broadcast_broadcaster, LOG_LEVEL_DBG);

#define DEFAULT_BIS_RTN         2
#define DEFAULT_BIS_INTERVAL_US 7500
#define DEFAULT_BIS_LATENCY_MS  10
#define DEFAULT_BIS_PHY         BT_GAP_LE_PHY_2M
#define DEFAULT_BIS_SDU         CONFIG_BT_ISO_TX_MTU
#define DEFAULT_BIS_PACKING     0
#define DEFAULT_BIS_FRAMING     0
#define DEFAULT_BIS_COUNT       CONFIG_BT_ISO_MAX_CHAN

NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
			  BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8, NULL);

static K_SEM_DEFINE(sem_big_complete, 0, 1);
static K_SEM_DEFINE(sem_big_term, 0, 1);
static struct k_work_delayable iso_send_work;
static uint32_t iso_send_count;
static uint8_t iso_data[CONFIG_BT_ISO_TX_MTU];
static uint8_t connected_bis;

static struct bt_iso_chan bis_iso_chans[CONFIG_BT_ISO_MAX_CHAN];
static struct bt_iso_chan *bis[CONFIG_BT_ISO_MAX_CHAN];
static struct bt_iso_big_create_param big_create_param = {
	.num_bis = DEFAULT_BIS_COUNT,
	.bis_channels = bis,
	.packing = DEFAULT_BIS_PACKING, /* 0 - sequential, 1 - interleaved */
	.framing = DEFAULT_BIS_FRAMING, /* 0 - unframed, 1 - framed */
	.interval = DEFAULT_BIS_INTERVAL_US, /* in microseconds */
	.latency = DEFAULT_BIS_LATENCY_MS, /* milliseconds */
};

static void iso_connected(struct bt_iso_chan *chan)
{
	LOG_INF("ISO Channel %p connected", chan);

	connected_bis++;
	if (connected_bis == big_create_param.num_bis) {
		k_sem_give(&sem_big_complete);
	}
}

static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
{
	LOG_INF("ISO Channel %p disconnected with reason 0x%02x",
	       chan, reason);

	connected_bis--;
	if (connected_bis == big_create_param.num_bis) {
		k_sem_give(&sem_big_term);
	}
}

static struct bt_iso_chan_ops iso_ops = {
	.connected	= iso_connected,
	.disconnected	= iso_disconnected,
};

static struct bt_iso_chan_io_qos iso_tx_qos = {
	.sdu = DEFAULT_BIS_SDU, /* bytes */
	.rtn = DEFAULT_BIS_RTN,
	.phy = DEFAULT_BIS_PHY,
};

static struct bt_iso_chan_qos bis_iso_qos = {
	.tx = &iso_tx_qos,
};

static size_t get_chars(char *buffer, size_t max_size)
{
	size_t pos = 0;

	while (pos < max_size) {
		char c = tolower(console_getchar());

		if (c == '\n' || c == '\r') {
			break;
		}
		printk("%c", c);
		buffer[pos++] = c;
	}
	printk("\n");
	buffer[pos] = '\0';

	return pos;
}

static int parse_rtn_arg(void)
{
	char buffer[4];
	size_t char_count;
	uint64_t rtn;

	printk("Set RTN (current %u, default %u)\n",
	       iso_tx_qos.rtn, DEFAULT_BIS_RTN);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_RTN;
	}

	rtn = strtoul(buffer, NULL, 0);
	if (rtn > BT_ISO_BROADCAST_RTN_MAX) {
		printk("Invalid RTN %llu", rtn);
		return -EINVAL;
	}

	return (int)rtn;
}

static int parse_interval_arg(void)
{
	char buffer[9];
	size_t char_count;
	uint64_t interval;

	printk("Set interval (us) (current %u, default %u)\n",
	       big_create_param.interval, DEFAULT_BIS_INTERVAL_US);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_INTERVAL_US;
	}

	interval = strtoul(buffer, NULL, 0);
	if (interval < BT_ISO_INTERVAL_MIN || interval > BT_ISO_INTERVAL_MAX) {
		printk("Invalid interval %llu", interval);
		return -EINVAL;
	}

	return (int)interval;
}

static int parse_latency_arg(void)
{
	char buffer[6];
	size_t char_count;
	uint64_t latency;

	printk("Set latency (ms) (current %u, default %u)\n",
	       big_create_param.latency, DEFAULT_BIS_LATENCY_MS);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_LATENCY_MS;
	}

	latency = strtoul(buffer, NULL, 0);
	if (latency < BT_ISO_LATENCY_MIN || latency > BT_ISO_LATENCY_MAX) {
		printk("Invalid latency %llu", latency);
		return -EINVAL;
	}

	return (int)latency;
}

static int parse_phy_arg(void)
{
	char buffer[3];
	size_t char_count;
	uint64_t phy;

	printk("Set PHY (current %u, default %u) - %u = 1M, %u = 2M, %u = Coded\n",
	       iso_tx_qos.phy, DEFAULT_BIS_PHY, BT_GAP_LE_PHY_1M,
	       BT_GAP_LE_PHY_2M, BT_GAP_LE_PHY_CODED);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_PHY;
	}

	phy = strtoul(buffer, NULL, 0);
	if (phy != BT_GAP_LE_PHY_1M &&
	    phy != BT_GAP_LE_PHY_2M &&
	    phy != BT_GAP_LE_PHY_CODED) {
		printk("Invalid PHY %llu", phy);
		return -EINVAL;
	}

	return (int)phy;
}

static int parse_sdu_arg(void)
{
	char buffer[6];
	size_t char_count;
	uint64_t sdu;

	printk("Set SDU (current %u, default %u)\n",
	       iso_tx_qos.sdu, DEFAULT_BIS_SDU);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_SDU;
	}

	sdu = strtoul(buffer, NULL, 0);
	if (sdu > MIN(BT_ISO_MAX_SDU, sizeof(iso_data))) {
		printk("Invalid SDU %llu", sdu);
		return -EINVAL;
	}

	return (int)sdu;
}

static int parse_packing_arg(void)
{
	char buffer[3];
	size_t char_count;
	uint64_t packing;

	printk("Set packing (current %u, default %u)\n",
	       big_create_param.packing, DEFAULT_BIS_PACKING);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_PACKING;
	}

	packing = strtoul(buffer, NULL, 0);
	if (packing != BT_ISO_PACKING_SEQUENTIAL &&
	    packing != BT_ISO_PACKING_INTERLEAVED) {
		printk("Invalid packing %llu", packing);
		return -EINVAL;
	}

	return (int)packing;
}

static int parse_framing_arg(void)
{
	char buffer[3];
	size_t char_count;
	uint64_t framing;

	printk("Set framing (current %u, default %u)\n",
	       big_create_param.framing, DEFAULT_BIS_FRAMING);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_FRAMING;
	}

	framing = strtoul(buffer, NULL, 0);
	if (framing != BT_ISO_FRAMING_UNFRAMED &&
	    framing != BT_ISO_FRAMING_FRAMED) {
		printk("Invalid framing %llu", framing);
		return -EINVAL;
	}

	return (int)framing;
}

static int parse_bis_count_arg(void)
{
	char buffer[4];
	size_t char_count;
	uint64_t bis_count;

	printk("Set BIS count (current %u, default %u)\n",
	       big_create_param.num_bis, DEFAULT_BIS_COUNT);

	char_count = get_chars(buffer, sizeof(buffer) - 1);
	if (char_count == 0) {
		return DEFAULT_BIS_COUNT;
	}

	bis_count = strtoul(buffer, NULL, 0);
	if (bis_count > MAX(BT_ISO_MAX_GROUP_ISO_COUNT, CONFIG_BT_ISO_MAX_CHAN)) {
		printk("Invalid BIS count %llu", bis_count);
		return -EINVAL;
	}

	return (int)bis_count;
}

static int parse_args(void)
{
	int rtn;
	int interval;
	int latency;
	int phy;
	int sdu;
	int packing;
	int framing;
	int bis_count;

	printk("Follow the prompts. Press enter to use default values.\n");

	rtn = parse_rtn_arg();
	if (rtn < 0) {
		return -EINVAL;
	}

	interval = parse_interval_arg();
	if (interval < 0) {
		return -EINVAL;
	}

	latency = parse_latency_arg();
	if (latency < 0) {
		return -EINVAL;
	}

	phy = parse_phy_arg();
	if (phy < 0) {
		return -EINVAL;
	}

	sdu = parse_sdu_arg();
	if (sdu < 0) {
		return -EINVAL;
	}

	packing = parse_packing_arg();
	if (packing < 0) {
		return -EINVAL;
	}

	framing = parse_framing_arg();
	if (framing < 0) {
		return -EINVAL;
	}

	bis_count = parse_bis_count_arg();
	if (bis_count < 0) {
		return -EINVAL;
	}

	iso_tx_qos.rtn = rtn;
	iso_tx_qos.phy = phy;
	iso_tx_qos.sdu = sdu;
	big_create_param.interval = interval;
	big_create_param.latency = latency;
	big_create_param.packing = packing;
	big_create_param.framing = framing;
	big_create_param.num_bis = bis_count;

	return 0;
}

static void iso_timer_timeout(struct k_work *work)
{
	int ret;
	struct net_buf *buf;

	/* Reschedule as early as possible to reduce time skewing
	 * Use the ISO interval minus a few microseconds to keep the buffer
	 * full. This might occasionally skip a transmit, i.e. where the host
	 * calls `bt_iso_chan_send` but the controller only sending a single
	 * ISO packet.
	 */
	k_work_reschedule(&iso_send_work, K_USEC(big_create_param.interval - 100));

	for (int i = 0; i < big_create_param.num_bis; i++) {
		buf = net_buf_alloc(&bis_tx_pool, K_FOREVER);
		if (buf == NULL) {
			LOG_ERR("Could not allocate buffer");
			return;
		}

		net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
		net_buf_add_mem(buf, iso_data, iso_tx_qos.sdu);
		ret = bt_iso_chan_send(&bis_iso_chans[i], buf);
		if (ret < 0) {
			LOG_ERR("Unable to broadcast data: %d", ret);
			net_buf_unref(buf);
			return;
		}
		iso_send_count++;

		if ((iso_send_count % 100) == 0) {
			LOG_INF("Sent %u packets", iso_send_count);
		}
	}
}

static int create_big(struct bt_le_ext_adv **adv, struct bt_iso_big **big)
{
	int err;

	/* Create a non-connectable non-scannable advertising set */
	LOG_INF("Creating Extended Advertising set");
	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, adv);
	if (err != 0) {
		LOG_ERR("Failed to create advertising set (err %d)", err);
		return err;
	}

	LOG_INF("Setting Periodic Advertising parameters");
	/* Set periodic advertising parameters */
	err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_DEFAULT);
	if (err != 0) {
		LOG_ERR("Failed to set periodic advertising parameters (err %d)",
			err);
		return err;
	}

	/* Enable Periodic Advertising */
	LOG_INF("Starting Periodic Advertising");
	err = bt_le_per_adv_start(*adv);
	if (err != 0) {
		LOG_ERR("Failed to enable periodic advertising (err %d)", err);
		return err;
	}

	/* Start extended advertising */
	LOG_INF("Starting Extended Advertising set");
	err = bt_le_ext_adv_start(*adv, BT_LE_EXT_ADV_START_DEFAULT);
	if (err != 0) {
		LOG_ERR("Failed to start extended advertising (err %d)", err);
		return err;
	}

	/* Prepare BIG */
	for (int i = 0; i < ARRAY_SIZE(bis_iso_chans); i++) {
		bis_iso_chans[i].ops = &iso_ops;
		bis_iso_chans[i].qos = &bis_iso_qos;
		bis[i] = &bis_iso_chans[i];
	}

	/* Create BIG */
	LOG_INF("Creating BIG");
	err = bt_iso_big_create(*adv, &big_create_param, big);
	if (err != 0) {
		LOG_ERR("Failed to create BIG (err %d)", err);
		return err;
	}

	LOG_INF("Waiting for BIG complete");
	err = k_sem_take(&sem_big_complete, K_FOREVER);
	if (err != 0) {
		LOG_ERR("failed to take sem_big_complete (err %d)", err);
		return err;
	}
	LOG_INF("BIG created");

	return 0;
}

static int delete_big(struct bt_le_ext_adv **adv, struct bt_iso_big **big)
{
	int err;

	err = bt_iso_big_terminate(*big);
	if (err != 0) {
		LOG_ERR("Failed to terminate BIG (err %d)", err);
		return err;
	}
	*big = NULL;

	err = bt_le_per_adv_stop(*adv);
	if (err != 0) {
		LOG_ERR("Failed to stop periodic advertising (err %d)", err);
		return err;
	}

	err = bt_le_ext_adv_stop(*adv);
	if (err != 0) {
		LOG_ERR("Failed to stop advertising (err %d)", err);
		return err;
	}

	err = bt_le_ext_adv_delete(*adv);
	if (err != 0) {
		LOG_ERR("Failed to delete advertiser (err %d)", err);
		return err;
	}

	*adv = NULL;

	return 0;
}

static void reset_sems(void)
{
	(void)k_sem_reset(&sem_big_complete);
	(void)k_sem_reset(&sem_big_term);
}

int test_run_broadcaster(void)
{
	struct bt_le_ext_adv *adv;
	struct bt_iso_big *big;
	int err;
	char c;
	static bool data_initialized;

	reset_sems();

	printk("Change settings (y/N)? (Current settings: rtn=%u, interval=%u, "
	       "latency=%u, phy=%u, sdu=%u, packing=%u, framing=%u, "
	       "bis_count=%u)\n", iso_tx_qos.rtn, big_create_param.interval,
	       big_create_param.latency, iso_tx_qos.phy, iso_tx_qos.sdu,
	       big_create_param.packing, big_create_param.framing,
	       big_create_param.num_bis);

	c = tolower(console_getchar());
	if (c == 'y') {
		err = parse_args();
		if (err != 0) {
			LOG_ERR("Could not parse args: %d", err);
			return err;
		}

		printk("New settings: rtn=%u, interval=%u, latency=%u, "
		       "phy=%u, sdu=%u, packing=%u, framing=%u, bis_count=%u\n",
		       iso_tx_qos.rtn, big_create_param.interval,
		       big_create_param.latency, iso_tx_qos.phy, iso_tx_qos.sdu,
		       big_create_param.packing, big_create_param.framing,
		       big_create_param.num_bis);
	}

	err = create_big(&adv, &big);
	if (err) {
		LOG_ERR("Could not create BIG: %d", err);
		return err;
	}

	iso_send_count = 0;

	if (!data_initialized) {
		/* Init data */
		for (int i = 0; i < iso_tx_qos.sdu; i++) {
			iso_data[i] = (uint8_t)i;
		}

		data_initialized = true;
	}

	k_work_init_delayable(&iso_send_work, iso_timer_timeout);
	k_work_schedule(&iso_send_work, K_MSEC(0));

	while (true) {
		printk("Press 'q' to end the broadcast\n");
		c = tolower(console_getchar());
		if (c == 'q') {
			break;
		}
	}

	LOG_INF("Ending broadcast");
	(void)k_work_cancel_delayable(&iso_send_work);

	err = delete_big(&adv, &big);
	if (err) {
		LOG_ERR("Could not delete BIG: %d", err);
		return err;
	}

	return 0;
}
