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

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

#define NAME_LEN 30

static struct bt_conn *default_conn;
bt_addr_le_t ext_addr;

enum bt_sample_scan_evt {
	BT_SAMPLE_EVT_EXT_ADV_FOUND,
	BT_SAMPLE_EVT_CONNECTED,
	BT_SAMPLE_EVT_DISCONNECTED,
	BT_SAMPLE_EVT_SCAN_DUE,
	BT_SAMPLE_EVT_MAX,
};

enum bt_sample_scan_st {
	BT_SAMPLE_ST_SCANNING,
	BT_SAMPLE_ST_CONNECTING,
	BT_SAMPLE_ST_CONNECTED,
	BT_SAMPLE_ST_COOLDOWN,
};

static volatile enum bt_sample_scan_st app_st = BT_SAMPLE_ST_SCANNING;

static ATOMIC_DEFINE(evt_bitmask, BT_SAMPLE_EVT_MAX);

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_scan_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) {
		bt_conn_unref(default_conn);
		default_conn = NULL;
		return;
	}

	raise_evt(BT_SAMPLE_EVT_CONNECTED);
}

static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
	bt_conn_unref(default_conn);
	default_conn = NULL;

	printk("Disconnected (reason 0x%02X)\n", reason);
}

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 void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
{
	if (info->adv_type & BT_GAP_ADV_TYPE_EXT_ADV &&
	    info->adv_props & BT_GAP_ADV_PROP_EXT_ADV &&
	    info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) {
		/* Attempt connection request for device with extended advertisements */
		memcpy(&ext_addr, info->addr, sizeof(ext_addr));
		raise_evt(BT_SAMPLE_EVT_EXT_ADV_FOUND);
	}
}

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

static inline int attempt_connection(void)
{
	int err;

	printk("Stopping scan\n");
	err = bt_le_scan_stop();
	if (err) {
		printk("Failed to stop scan: %d\n", err);
		return err;
	}

	err = bt_conn_le_create(&ext_addr, BT_CONN_LE_CREATE_CONN,
		BT_LE_CONN_PARAM_DEFAULT, &default_conn);
	if (err) {
		printk("Failed to establish conn: %d\n", err);
		return err;
	}

	return 0;
}

static inline int start_scanning(void)
{
	int err;

	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
	if (err) {
		printk("failed (err %d)\n", err);
	}

	return err;
}

int main(void)
{
	int err;

	printk("Starting Extended Advertising Demo [Scanner]\n");

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

	bt_le_scan_cb_register(&scan_callbacks);

	err = start_scanning();
	if (err) {
		return err;
	}

	while (true) {
		(void)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_EXT_ADV_FOUND) &&
		    app_st == BT_SAMPLE_ST_SCANNING) {

			printk("Found extended advertisement packet!\n");
			app_st = BT_SAMPLE_ST_CONNECTING;
			err = attempt_connection();
			if (err) {
				return err;
			}

		} else if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_CONNECTED) &&
			   (app_st == BT_SAMPLE_ST_CONNECTING)) {

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

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

			printk("Disconnected, cooldown for 5 seconds!\n");
			app_st = BT_SAMPLE_ST_COOLDOWN;

			/* Wait a few seconds before starting to re-scan again... */
			k_sleep(K_SECONDS(5));

			raise_evt(BT_SAMPLE_EVT_SCAN_DUE);

		} else if (atomic_test_and_clear_bit(evt_bitmask, BT_SAMPLE_EVT_SCAN_DUE) &&
			   (app_st == BT_SAMPLE_ST_COOLDOWN)) {

			printk("Starting to scan for extended adv\n");
			app_st = BT_SAMPLE_ST_SCANNING;
			err = start_scanning();
			if (err) {
				return err;
			}

		}
	}

	return 0;
}
