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

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

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

#define DEVICE_NAME	CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME))

#define BT_INTERVAL_TO_MS(interval) ((interval) * 5 / 4)
#define PA_RETRY_COUNT 6
#define ISO_RETRY_COUNT 10

struct iso_recv_stats {
	uint32_t     iso_recv_count;
	uint32_t     iso_lost_count;
};

static bool         broadcaster_found;
static bool         per_adv_lost;
static bool         big_sync_lost;
static bool         biginfo_received;
static bt_addr_le_t per_addr;
static uint8_t      per_sid;
static uint16_t     per_interval_ms;
static uint16_t     iso_interval_ms;
static uint8_t      bis_count;
static uint32_t     last_received_counter;
static int64_t      big_sync_start_time;
static size_t       big_sync_count;

static struct iso_recv_stats stats_current_sync;
static struct iso_recv_stats stats_overall;

static K_SEM_DEFINE(sem_per_adv, 0, 1);
static K_SEM_DEFINE(sem_per_sync, 0, 1);
static K_SEM_DEFINE(sem_per_sync_lost, 0, 1);
static K_SEM_DEFINE(sem_per_big_info, 0, 1);
static K_SEM_DEFINE(sem_big_sync, 0, 1);
static K_SEM_DEFINE(sem_big_sync_lost, 0, 1);

static const char *phy2str(uint8_t phy)
{
	switch (phy) {
	case 0: return "No packets";
	case BT_GAP_LE_PHY_1M: return "LE 1M";
	case BT_GAP_LE_PHY_2M: return "LE 2M";
	case BT_GAP_LE_PHY_CODED: return "LE Coded";
	default: return "Unknown";
	}
}

static bool data_cb(struct bt_data *data, void *user_data)
{
	char *name = user_data;
	uint8_t len;

	switch (data->type) {
	case BT_DATA_NAME_SHORTENED:
	case BT_DATA_NAME_COMPLETE:
		len = MIN(data->data_len, DEVICE_NAME_LEN - 1);
		memcpy(name, data->data, len);
		name[len] = '\0';
		return false;
	default:
		return true;
	}
}

static void scan_recv(const struct bt_le_scan_recv_info *info,
		      struct net_buf_simple *buf)
{
	char le_addr[BT_ADDR_LE_STR_LEN];
	char name[DEVICE_NAME_LEN];

	if (broadcaster_found) {
		return;
	}

	(void)memset(name, 0, sizeof(name));

	bt_data_parse(buf, data_cb, name);

	if (strncmp(DEVICE_NAME, name, strlen(DEVICE_NAME))) {
		return;
	}

	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));

	LOG_INF("Found broadcaster with address %s (RSSI %i)",
		le_addr, info->rssi);

	broadcaster_found = true;

	per_sid = info->sid;
	per_interval_ms = BT_INTERVAL_TO_MS(info->interval);
	bt_addr_le_copy(&per_addr, info->addr);

	k_sem_give(&sem_per_adv);
}

static struct bt_le_scan_cb scan_callbacks = {
	.recv = scan_recv,
};

static void sync_cb(struct bt_le_per_adv_sync *sync,
		    struct bt_le_per_adv_sync_synced_info *info)
{
	LOG_INF("Periodic advertisement synced");

	k_sem_give(&sem_per_sync);
}

static void term_cb(struct bt_le_per_adv_sync *sync,
		    const struct bt_le_per_adv_sync_term_info *info)
{
	LOG_INF("Periodic advertisement sync terminated");

	per_adv_lost = true;
	k_sem_give(&sem_per_sync_lost);
}

static void biginfo_cb(struct bt_le_per_adv_sync *sync,
		       const struct bt_iso_biginfo *biginfo)
{
	if (biginfo_received) {
		return;
	}

	LOG_INF("BIGinfo received: num_bis %u, nse %u, interval %.2f ms, "
		"bn %u, pto %u, irc %u, max_pdu %u, sdu_interval %u us, "
		"max_sdu %u, phy %s, %s framing, %sencrypted",
		biginfo->num_bis, biginfo->sub_evt_count,
		BT_INTERVAL_TO_MS((float)biginfo->iso_interval),
		biginfo->burst_number, biginfo->offset, biginfo->rep_count,
		biginfo->max_pdu, biginfo->sdu_interval, biginfo->max_sdu,
		phy2str(biginfo->phy), biginfo->framing ? "with" : "without",
		biginfo->encryption ? "" : "not ");

	iso_interval_ms = BT_INTERVAL_TO_MS(biginfo->iso_interval);
	bis_count = MIN(biginfo->num_bis, CONFIG_BT_ISO_MAX_CHAN);
	biginfo_received = true;
	k_sem_give(&sem_per_big_info);
}

static struct bt_le_per_adv_sync_cb sync_callbacks = {
	.synced = sync_cb,
	.term = term_cb,
	.biginfo = biginfo_cb,
};

static void print_stats(char *name, struct iso_recv_stats *stats)
{
	uint32_t total_packets;

	total_packets = stats->iso_recv_count + stats->iso_lost_count;

	LOG_INF("%s: Received %u/%u (%.2f%%) - Total packets lost %u",
		name, stats->iso_recv_count, total_packets,
		(float)stats->iso_recv_count * 100 / total_packets,
		stats->iso_lost_count);

}

static void iso_recv(struct bt_iso_chan *chan,
		     const struct bt_iso_recv_info *info,
		     struct net_buf *buf)
{
	uint32_t total_packets;
	static bool stats_latest_arr[1000];
	static size_t stats_latest_arr_pos;

	/* NOTE: The packets received may be on different BISes */

	if (info->flags == BT_ISO_FLAGS_VALID) {
		stats_current_sync.iso_recv_count++;
		stats_overall.iso_recv_count++;
		stats_latest_arr[stats_latest_arr_pos++] = true;
	} else {
		stats_current_sync.iso_lost_count++;
		stats_overall.iso_lost_count++;
		stats_latest_arr[stats_latest_arr_pos++] = false;
	}

	if (stats_latest_arr_pos == sizeof(stats_latest_arr)) {
		stats_latest_arr_pos = 0;
	}

	total_packets = stats_overall.iso_recv_count + stats_overall.iso_lost_count;

	if ((total_packets % 100) == 0) {
		struct iso_recv_stats stats_latest = { 0 };

		for (int i = 0; i < ARRAY_SIZE(stats_latest_arr); i++) {
			/* If we have not yet received 1000 packets, break
			 * early
			 */
			if (i == total_packets) {
				break;
			}

			if (stats_latest_arr[i]) {
				stats_latest.iso_recv_count++;
			} else {
				stats_latest.iso_lost_count++;
			}
		}

		print_stats("Overall     ", &stats_overall);
		print_stats("Current Sync", &stats_current_sync);
		print_stats("Latest 1000 ", &stats_latest);
		LOG_INF(""); /* Empty line to separate the stats */
	}
}

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

	big_sync_start_time = k_uptime_get();

	k_sem_give(&sem_big_sync);
}

static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
{
	/* Calculate cumulative moving average - Be aware that this may
	 * cause overflow at sufficiently large counts or durations
	 */
	static int64_t average_duration;
	uint64_t big_sync_duration = k_uptime_get() - big_sync_start_time;
	uint64_t total_duration = big_sync_duration + (big_sync_count - 1) * average_duration;

	average_duration = total_duration / big_sync_count;

	LOG_INF("ISO Channel %p disconnected with reason 0x%02x after "
		"%llu milliseconds (average duration %llu)",
		chan, reason, big_sync_duration, average_duration);

	big_sync_lost = true;

	k_sem_give(&sem_big_sync_lost);
}

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

static struct bt_iso_chan_io_qos iso_rx_qos;

static struct bt_iso_chan_qos bis_iso_qos = {
	.rx = &iso_rx_qos,
};


static int start_scan(void)
{
	int err;

	err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
	if (err != 0) {
		LOG_ERR("Scan start failed (err %d)", err);
		return err;
	}

	LOG_INF("Scan started");

	return 0;
}

static int stop_scan(void)
{
	int err;

	err = bt_le_scan_stop();
	if (err != 0) {
		LOG_ERR("Scan stop failed (err %d)", err);
		return err;
	}
	LOG_INF("Scan stopped");

	return 0;
}

static int create_pa_sync(struct bt_le_per_adv_sync **sync)
{
	struct bt_le_per_adv_sync_param sync_create_param;
	int err;
	uint32_t sem_timeout;

	LOG_INF("Creating Periodic Advertising Sync");
	bt_addr_le_copy(&sync_create_param.addr, &per_addr);
	sync_create_param.options = 0;
	sync_create_param.sid = per_sid;
	sync_create_param.skip = 0;
	sync_create_param.timeout = (per_interval_ms * PA_RETRY_COUNT) / 10;
	sem_timeout = per_interval_ms * PA_RETRY_COUNT;
	err = bt_le_per_adv_sync_create(&sync_create_param, sync);
	if (err != 0) {
		LOG_ERR("Periodic advertisement sync create failed (err %d)",
		       err);
		return err;
	}

	LOG_INF("Waiting for periodic sync");
	err = k_sem_take(&sem_per_sync, K_MSEC(sem_timeout));
	if (err != 0) {
		LOG_INF("failed to take sem_per_sync (err %d)", err);

		LOG_INF("Deleting Periodic Advertising Sync");
		err = bt_le_per_adv_sync_delete(*sync);
		if (err != 0) {
			LOG_ERR("Failed to delete Periodic advertisement sync (err %d)",
			       err);

			return err;
		}
	}
	LOG_INF("Periodic sync established");

	return 0;
}

static int create_big_sync(struct bt_iso_big **big, struct bt_le_per_adv_sync *sync)
{
	int err;
	uint32_t sem_timeout = per_interval_ms * PA_RETRY_COUNT;
	uint32_t sync_timeout_ms;
	static struct bt_iso_chan bis_iso_chan[CONFIG_BT_ISO_MAX_CHAN];
	static struct bt_iso_chan *bis[CONFIG_BT_ISO_MAX_CHAN];
	struct bt_iso_big_sync_param big_sync_param = {
		.bis_channels = bis,
		.num_bis = 0,
		.bis_bitfield = 0,
		.mse = 0,
		.sync_timeout = 0
	};

	for (int i = 0; i < ARRAY_SIZE(bis_iso_chan); i++) {
		bis_iso_chan[i].ops = &iso_ops;
		bis_iso_chan[i].qos = &bis_iso_qos;
		bis[i] = &bis_iso_chan[i];
	}

	LOG_INF("Waiting for BIG info");
	err = k_sem_take(&sem_per_big_info, K_MSEC(sem_timeout));
	if (err != 0) {
		LOG_ERR("failed to take sem_per_big_info (err %d)", err);
		return err;
	}

	sync_timeout_ms = iso_interval_ms * ISO_RETRY_COUNT;
	big_sync_param.sync_timeout = CLAMP(sync_timeout_ms / 10, 0x000A, 0x4000); /* 10 ms units */
	big_sync_param.num_bis = bis_count;
	/* BIS indexes start from 0x01, so add one to `i` */
	for (int i = 1; i <= big_sync_param.num_bis; i++) {
		big_sync_param.bis_bitfield |= BIT(i);
	}

	LOG_INF("Syncing to BIG");
	err = bt_iso_big_sync(sync, &big_sync_param, big);
	if (err != 0) {
		LOG_ERR("BIG sync failed (err %d)", err);
		return err;
	}

	LOG_INF("Waiting for BIG sync");
	err = k_sem_take(&sem_big_sync, K_MSEC(sem_timeout));
	if (err != 0) {
		LOG_ERR("failed to take sem_big_sync (err %d)", err);
		return err;
	}
	LOG_INF("BIG sync established");

	big_sync_count++;

	return 0;
}

static int cleanup(struct bt_le_per_adv_sync *sync, struct bt_iso_big *big)
{
	int pa_err = 0;
	int big_err = 0;

	if (!per_adv_lost && sync) {
		LOG_INF("Deleting Periodic advertisement Sync");
		pa_err = bt_le_per_adv_sync_delete(sync);
		if (pa_err != 0) {
			LOG_ERR("Failed to delete Periodic advertisement sync (err %d)",
				pa_err);
		}
	}

	if (!big_sync_lost && big) {
		LOG_INF("Terminating BIG Sync");
		big_err = bt_iso_big_terminate(big);
		if (big_err != 0) {
			LOG_ERR("BIG terminate failed (err %d)", big_err);
		}
	}

	if (pa_err != 0 || big_err != 0) {
		LOG_ERR("Cleanup failed (%d), recommend restart application to "
		       "avoid any potential leftovers",
		       pa_err != 0 ? pa_err : big_err);
	}

	return pa_err != 0 ? pa_err : big_err;
}

static void reset_sems(void)
{
	(void)k_sem_reset(&sem_per_adv);
	(void)k_sem_reset(&sem_per_sync);
	(void)k_sem_reset(&sem_per_sync_lost);
	(void)k_sem_reset(&sem_per_big_info);
	(void)k_sem_reset(&sem_big_sync);
	(void)k_sem_reset(&sem_big_sync_lost);
}

int test_run_receiver(void)
{
	struct bt_le_per_adv_sync *sync = NULL;
	struct bt_iso_big *big = NULL;
	int err;
	static bool callbacks_registered;

	broadcaster_found = false;
	per_adv_lost = false;
	big_sync_lost = false;
	biginfo_received = false;
	reset_sems();

	if (!callbacks_registered) {
		bt_le_per_adv_sync_cb_register(&sync_callbacks);
		bt_le_scan_cb_register(&scan_callbacks);
		callbacks_registered = true;
	}

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

	LOG_INF("Waiting for periodic advertiser");
	err = k_sem_take(&sem_per_adv, K_FOREVER);
	if (err != 0) {
		LOG_ERR("failed to take sem_per_adv (err %d)", err);
		return err;
	}
	LOG_INF("Periodic advertiser found");

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

	err = create_pa_sync(&sync);
	if (err != 0) {
		return err;
	}

	last_received_counter = 0;
	memset(&stats_current_sync, 0, sizeof(stats_current_sync));
	big_sync_start_time = 0;

	err = create_big_sync(&big, sync);
	if (err != 0) {
		(void)cleanup(sync, big);
		return err;
	}

	err = k_sem_take(&sem_big_sync_lost, K_FOREVER);
	if (err != 0) {
		LOG_ERR("failed to take sem_big_sync_lost (err %d)", err);
		return err;
	}
	LOG_INF("BIG sync lost, returning");
	/* TODO: Add support to cancel the test early */

	return cleanup(sync, big);
}
