/*
 * Copyright (c) 2022 Codecoup
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/printk.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/byteorder.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/audio/pacs.h>
#include <zephyr/bluetooth/audio/csip.h>
#include <zephyr/bluetooth/services/ias.h>

#include "hap_ha.h"

#define MANDATORY_SINK_CONTEXT (BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | \
				BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | \
				BT_AUDIO_CONTEXT_TYPE_MEDIA | \
				BT_AUDIO_CONTEXT_TYPE_LIVE)

#define AVAILABLE_SINK_CONTEXT   MANDATORY_SINK_CONTEXT
#define AVAILABLE_SOURCE_CONTEXT MANDATORY_SINK_CONTEXT

static uint8_t unicast_server_addata[] = {
	BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */
	BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */
	BT_BYTES_LIST_LE16(AVAILABLE_SINK_CONTEXT),
	BT_BYTES_LIST_LE16(AVAILABLE_SOURCE_CONTEXT),
	0x00, /* Metadata length */
};

static uint8_t csis_rsi_addata[BT_CSIP_RSI_SIZE];

/* TODO: Expand with BAP data */
static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL)),
#if defined(CONFIG_BT_CSIP_SET_MEMBER)
	BT_DATA(BT_DATA_CSIS_RSI, csis_rsi_addata, ARRAY_SIZE(csis_rsi_addata)),
#endif /* CONFIG_BT_CSIP_SET_MEMBER */
	BT_DATA(BT_DATA_SVC_DATA16, unicast_server_addata, ARRAY_SIZE(unicast_server_addata)),
};

static struct k_work_delayable adv_work;
static struct bt_le_ext_adv *ext_adv;

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	/* Restart advertising after disconnection */
	k_work_schedule(&adv_work, K_SECONDS(1));
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.disconnected = disconnected,
};

#if defined(CONFIG_BT_PRIVACY) && defined(CONFIG_BT_CSIP_SET_MEMBER)
static bool adv_rpa_expired_cb(struct bt_le_ext_adv *adv)
{
	char rsi_str[13];
	int err;

	err = csip_generate_rsi(csis_rsi_addata);
	if (err != 0) {
		printk("Failed to generate RSI (err %d)\n", err);
		return false;
	}

	snprintk(rsi_str, ARRAY_SIZE(rsi_str), "%02x%02x%02x%02x%02x%02x",
		 csis_rsi_addata[0], csis_rsi_addata[1], csis_rsi_addata[2],
		 csis_rsi_addata[3], csis_rsi_addata[4], csis_rsi_addata[5]);

	printk("PRSI: 0x%s\n", rsi_str);

	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		printk("Failed to set advertising data (err %d)\n", err);
		return false;
	}

	return true;
}
#endif /* CONFIG_BT_PRIVACY && CONFIG_BT_CSIP_SET_MEMBER */

static const struct bt_le_ext_adv_cb adv_cb = {
#if defined(CONFIG_BT_PRIVACY) && defined(CONFIG_BT_CSIP_SET_MEMBER)
	.rpa_expired = adv_rpa_expired_cb,
#endif /* CONFIG_BT_PRIVACY && CONFIG_BT_CSIP_SET_MEMBER */
};

static void adv_work_handler(struct k_work *work)
{
	int err;

	if (ext_adv == NULL) {
		/* Create a non-connectable non-scannable advertising set */
		err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN_NAME, &adv_cb, &ext_adv);
		if (err) {
			printk("Failed to create advertising set (err %d)\n", err);
		}

		err = bt_le_ext_adv_set_data(ext_adv, ad, ARRAY_SIZE(ad), NULL, 0);
		if (err) {
			printk("Failed to set advertising data (err %d)\n", err);
		}

		__ASSERT_NO_MSG(err == 0);
	}

	err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
	if (err) {
		printk("Failed to start advertising set (err %d)\n", err);
	} else {
		printk("Advertising successfully started\n");
	}
}

#if defined(CONFIG_BT_IAS)
static void alert_stop(void)
{
	printk("Alert stopped\n");
}

static void alert_start(void)
{
	printk("Mild alert started\n");
}

static void alert_high_start(void)
{
	printk("High alert started\n");
}

BT_IAS_CB_DEFINE(ias_callbacks) = {
	.no_alert = alert_stop,
	.mild_alert = alert_start,
	.high_alert = alert_high_start,
};
#endif /* CONFIG_BT_IAS */

int main(void)
{
	int err;

	err = bt_enable(NULL);
	if (err != 0) {
		printk("Bluetooth init failed (err %d)\n", err);
		return 0;
	}

	printk("Bluetooth initialized\n");

	err = has_server_init();
	if (err != 0) {
		printk("HAS Server init failed (err %d)\n", err);
		return 0;
	}

	err = bap_unicast_sr_init();
	if (err != 0) {
		printk("BAP Unicast Server init failed (err %d)\n", err);
		return 0;
	}

	if (IS_ENABLED(CONFIG_HAP_HA_HEARING_AID_BINAURAL)) {
		err = csip_set_member_init();
		if (err != 0) {
			printk("CSIP Set Member init failed (err %d)\n", err);
			return 0;
		}

		err = csip_generate_rsi(csis_rsi_addata);
		if (err != 0) {
			printk("Failed to generate RSI (err %d)\n", err);
			return 0;
		}
	}

	err = vcp_vol_renderer_init();
	if (err != 0) {
		printk("VCP Volume Renderer init failed (err %d)\n", err);
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) {
		err = micp_mic_dev_init();
		if (err != 0) {
			printk("MICP Microphone Device init failed (err %d)\n", err);
			return 0;
		}
	}

	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT)) {
		err = ccp_call_ctrl_init();
		if (err != 0) {
			printk("MICP Microphone Device init failed (err %d)\n", err);
			return 0;
		}
	}

	if (IS_ENABLED(CONFIG_HAP_HA_HEARING_AID_BANDED)) {
		/* HAP_d1.0r00; 3.7 BAP Unicast Server role requirements
		 * A Banded Hearing Aid in the HA role shall set the
		 * Front Left and the Front Right bits to a value of 0b1
		 * in the Sink Audio Locations characteristic value.
		 */
		bt_pacs_set_location(BT_AUDIO_DIR_SINK,
				    (BT_AUDIO_LOCATION_FRONT_LEFT |
				     BT_AUDIO_LOCATION_FRONT_RIGHT));
	} else {
		bt_pacs_set_location(BT_AUDIO_DIR_SINK,
				     BT_AUDIO_LOCATION_FRONT_LEFT);
	}

	bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
				       AVAILABLE_SINK_CONTEXT);

	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) {
		bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
				     BT_AUDIO_LOCATION_FRONT_LEFT);
		bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
					       AVAILABLE_SOURCE_CONTEXT);
	}

	k_work_init_delayable(&adv_work, adv_work_handler);
	k_work_schedule(&adv_work, K_NO_WAIT);
	return 0;
}
