/**
 * Copyright (c) 2024 Croxel, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gap.h>

static struct bt_conn *default_conn;

enum bt_sample_adv_evt {
	BT_SAMPLE_EVT_CONNECTED,
	BT_SAMPLE_EVT_DISCONNECTED,
	BT_SAMPLE_EVT_MAX,
};

enum bt_sample_adv_st {
	BT_SAMPLE_ST_ADV,
	BT_SAMPLE_ST_CONNECTED,
};

static ATOMIC_DEFINE(evt_bitmask, BT_SAMPLE_EVT_MAX);

static volatile enum bt_sample_adv_st app_st = BT_SAMPLE_ST_ADV;

static struct k_poll_signal poll_sig = K_POLL_SIGNAL_INITIALIZER(poll_sig);
static struct k_poll_event poll_evt = K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
						K_POLL_MODE_NOTIFY_ONLY, &poll_sig);

static void raise_evt(enum bt_sample_adv_evt evt)
{
	(void)atomic_set_bit(evt_bitmask, evt);
	k_poll_signal_raise(poll_evt.signal, 1);
}

static void connected_cb(struct bt_conn *conn, uint8_t err)
{
	printk("Connected (err 0x%02X)\n", err);

	if (err) {
		return;
	}

	__ASSERT(!default_conn, "Attempting to override existing connection object!");
	default_conn = bt_conn_ref(conn);

	raise_evt(BT_SAMPLE_EVT_CONNECTED);
}

static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected (reason 0x%02X)\n", reason);

	__ASSERT(conn == default_conn, "Unexpected disconnected callback");

	bt_conn_unref(default_conn);
	default_conn = NULL;
}

static void recycled_cb(void)
{
	printk("Connection object available from previous conn. Disconnect is complete!\n");
	raise_evt(BT_SAMPLE_EVT_DISCONNECTED);
}

BT_CONN_CB_DEFINE(conn_cb) = {
	.connected = connected_cb,
	.disconnected = disconnected_cb,
	.recycled = recycled_cb,
};

static int start_advertising(struct bt_le_ext_adv *adv)
{
	int err;

	printk("Starting Extended Advertising\n");
	err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
	if (err) {
		printk("Failed to start extended advertising (err %d)\n", err);
	}

	return err;
}

int main(void)
{
	int err;
	struct bt_le_ext_adv *adv;

	printk("Starting Extended Advertising Demo\n");

	/* Initialize the Bluetooth Subsystem */
	err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return err;
	}

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

	err = start_advertising(adv);
	if (err) {
		return err;
	}

	while (true) {
		k_poll(&poll_evt, 1, K_FOREVER);

		k_poll_signal_reset(poll_evt.signal);
		poll_evt.state = K_POLL_STATE_NOT_READY;

		/* Identify event and act upon if applicable */
		if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_CONNECTED) &&
		    app_st == BT_SAMPLE_ST_ADV) {

			printk("Connected state!\n");
			app_st = BT_SAMPLE_ST_CONNECTED;

			printk("Initiating disconnect within 5 seconds...\n");
			k_sleep(K_SECONDS(5));

			bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);

		} else if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_DISCONNECTED) &&
			   app_st == BT_SAMPLE_ST_CONNECTED) {

			printk("Disconnected state! Restarting advertising\n");
			app_st = BT_SAMPLE_ST_ADV;
			err = start_advertising(adv);
			if (err) {
				return err;
			}
		}
	}

	return err;
}
