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

#include "utils.h"
#include "argparse.h"
#include "bs_pc_backchannel.h"

#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/__assert.h>

/* Custom Service Variables */
static const struct bt_uuid_128 test_svc_uuid = BT_UUID_INIT_128(
	0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
	0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);

static const struct bt_uuid_128 test_svc_uuid_2 = BT_UUID_INIT_128(
	0xf1, 0xdd, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
	0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);

static const struct bt_uuid_128 test_chrc_uuid = BT_UUID_INIT_128(
	0xf2, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
	0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);

static uint8_t test_value[] = { 'T', 'e', 's', 't', '\0' };

DEFINE_FLAG(flag_client_read);

static ssize_t read_test(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			void *buf, uint16_t len, uint16_t offset)
{
	const char *value = attr->user_data;

	printk("Client has read from test char\n");
	SET_FLAG(flag_client_read);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
				 strlen(value));
}

void wait_for_client_read(void)
{
	WAIT_FOR_FLAG(flag_client_read);
}

static ssize_t write_test(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 const void *buf, uint16_t len, uint16_t offset,
			 uint8_t flags)
{
	uint8_t *value = attr->user_data;

	printk("Client has written to test char\n");

	if (offset + len > sizeof(test_value)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	memcpy(value + offset, buf, len);

	return len;
}

static struct bt_gatt_attr test_attrs[] = {
	/* Vendor Primary Service Declaration */
	BT_GATT_PRIMARY_SERVICE(&test_svc_uuid),

	BT_GATT_CHARACTERISTIC(&test_chrc_uuid.uuid,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_READ |
			       BT_GATT_PERM_WRITE,
			       read_test, write_test, test_value),
};

static struct bt_gatt_attr test_attrs_2[] = {
	/* Vendor Primary Service Declaration */
	BT_GATT_PRIMARY_SERVICE(&test_svc_uuid_2),

	BT_GATT_CHARACTERISTIC(&test_chrc_uuid.uuid,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_READ_ENCRYPT |
			       BT_GATT_PERM_WRITE_ENCRYPT,
			       read_test, write_test, test_value),
};

static struct bt_gatt_service test_svc = BT_GATT_SERVICE(test_attrs);
static struct bt_gatt_service test_svc_2 = BT_GATT_SERVICE(test_attrs_2);

void gatt_register_service_1(void)
{
	int err = bt_gatt_service_register(&test_svc);

	__ASSERT(!err, "Failed to register GATT service (err %d)\n", err);
}

void gatt_register_service_2(void)
{
	/* This service is only used to trigger a GATT DB change.
	 * No reads or writes will be attempted.
	 */
	int err = bt_gatt_service_register(&test_svc_2);

	__ASSERT(!err, "Failed to register GATT service (err %d)\n", err);
}

/* We need to discover:
 * - Dynamic service
 * - Client Features (to set robust caching)
 * - Service Changed (to sub to indications)
 */
enum GATT_HANDLES {
CLIENT_FEATURES,
SERVICE_CHANGED,
TEST_CHAR,
NUM_HANDLES,
};

uint16_t gatt_handles[NUM_HANDLES] = {0};

DEFINE_FLAG(flag_discovered);

static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	if (attr == NULL) {
		for (int i = 0; i < ARRAY_SIZE(gatt_handles); i++) {
			printk("handle[%d] = 0x%x\n", i, gatt_handles[i]);

			if (gatt_handles[i] == 0) {
				FAIL("Did not discover all characteristics\n");
			}
		}

		(void)memset(params, 0, sizeof(*params));

		SET_FLAG(flag_discovered);

		return BT_GATT_ITER_STOP;
	}

	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data;

		if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_CLIENT_FEATURES) == 0) {
			printk("Found client supported features\n");
			gatt_handles[CLIENT_FEATURES] = chrc->value_handle;

		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_GATT_SC) == 0) {
			printk("Found service changed\n");
			gatt_handles[SERVICE_CHANGED] = chrc->value_handle;

		} else if (bt_uuid_cmp(chrc->uuid, &test_chrc_uuid.uuid) == 0) {
			printk("Found test characteristic\n");
			gatt_handles[TEST_CHAR] = chrc->value_handle;
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

DEFINE_FLAG(flag_sc_indicated);
static uint8_t sc_indicated(struct bt_conn *conn,
			    struct bt_gatt_subscribe_params *params,
			    const void *data, uint16_t length)
{
	if (!data) {
		params->value_handle = 0U;
		return BT_GATT_ITER_STOP;
	}

	printk("SC received\n");
	SET_FLAG(flag_sc_indicated);

	return BT_GATT_ITER_CONTINUE;
}

void wait_for_sc_indication(void)
{
	WAIT_FOR_FLAG(flag_sc_indicated);
}

DEFINE_FLAG(flag_sc_subscribed);
static void sc_subscribed(struct bt_conn *conn, uint8_t err,
			  struct bt_gatt_subscribe_params *params)
{
	if (params->value) {
		printk("SC subscribed\n");
		SET_FLAG(flag_sc_subscribed);
	} else {
		printk("SC unsubscribed\n");
		UNSET_FLAG(flag_sc_subscribed);
	}
}

static struct bt_gatt_discover_params disc_params;
static struct bt_gatt_subscribe_params subscribe_params;
void gatt_subscribe_to_service_changed(bool subscribe)
{
	int err;

	subscribe_params.value_handle = gatt_handles[SERVICE_CHANGED];
	subscribe_params.notify = sc_indicated;
	subscribe_params.subscribe = sc_subscribed;

	if (subscribe) {
		/* Use the BT_GATT_AUTO_DISCOVER_CCC feature */
		subscribe_params.ccc_handle = 0;
		subscribe_params.disc_params = &disc_params,
		subscribe_params.value = BT_GATT_CCC_INDICATE;
		subscribe_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

		err = bt_gatt_subscribe(get_conn(), &subscribe_params);
		WAIT_FOR_FLAG(flag_sc_subscribed);
	} else {
		/* Params are already set to the correct values by the previous
		 * call of this fn.
		 */
		err = bt_gatt_unsubscribe(get_conn(), &subscribe_params);
		WAIT_FOR_FLAG_UNSET(flag_sc_subscribed);
	}

	if (err != 0) {
		FAIL("Subscription failed(err %d)\n", err);
	} else {
		printk("%subscribed %s SC indications\n",
		       subscribe ? "S" : "Uns",
		       subscribe ? "to" : "from");
	}
}

void gatt_discover(void)
{
	static struct bt_gatt_discover_params discover_params;
	int err;

	printk("Discovering services and characteristics\n");
	UNSET_FLAG(flag_discovered);

	discover_params.uuid = NULL;
	discover_params.func = discover_func;
	discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

	err = bt_gatt_discover(get_conn(), &discover_params);
	if (err != 0) {
		FAIL("Discover failed(err %d)\n", err);
	}

	WAIT_FOR_FLAG(flag_discovered);
	printk("Discover complete\n");
}

DEFINE_FLAG(flag_written);

static void write_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{
	if (err != BT_ATT_ERR_SUCCESS) {
		FAIL("Write failed: 0x%02X\n", err);
	}

	SET_FLAG(flag_written);
}

#define CF_BIT_ROBUST_CACHING 0
void activate_robust_caching(void)
{
	int err;

	static const uint8_t csf = BIT(CF_BIT_ROBUST_CACHING);
	static struct bt_gatt_write_params write_params = {
		.func = write_cb,
		.offset = 0,
		.data = &csf,
		.length = sizeof(csf),
	};

	write_params.handle = gatt_handles[CLIENT_FEATURES];

	UNSET_FLAG(flag_written);
	err = bt_gatt_write(get_conn(), &write_params);

	__ASSERT(!err, "Failed to enable robust caching\n");

	WAIT_FOR_FLAG(flag_written);
	printk("Robust caching enabled\n");
}

DEFINE_FLAG(flag_read);

static uint8_t _expect_success(struct bt_conn *conn, uint8_t err,
			       struct bt_gatt_read_params *params,
			       const void *data, uint16_t length)
{
	/* printk("GATT read cb: err 0x%02X\n", err); */
	__ASSERT(err == 0, "Failed to read: err 0x%x\n", err);

	SET_FLAG(flag_read);

	return 0;
}

static uint8_t _expect_out_of_sync_cb(struct bt_conn *conn, uint8_t err,
				     struct bt_gatt_read_params *params,
				     const void *data, uint16_t length)
{
	/* printk("GATT read cb: err 0x%02X\n", err); */
	__ASSERT(err == BT_ATT_ERR_DB_OUT_OF_SYNC,
		 "Didn't get expected error code: err 0x%x\n", err);

	SET_FLAG(flag_read);

	return 0;
}

static void read_char(uint16_t handle, bool expect_success)
{
	int err;

	struct bt_gatt_read_params read_params = {
		.handle_count = 1,
		.single = {
			.handle = handle,
			.offset = 0,
		},
	};

	if (expect_success) {
		read_params.func = _expect_success;
	} else {
		read_params.func = _expect_out_of_sync_cb;
	}

	UNSET_FLAG(flag_read);

	err = bt_gatt_read(get_conn(), &read_params);
	__ASSERT(!err, "Failed to read char\n");

	WAIT_FOR_FLAG(flag_read);
}

void read_test_char(bool expect_success)
{
	read_char(gatt_handles[TEST_CHAR], expect_success);
}

void gatt_clear_flags(void)
{
	UNSET_FLAG(flag_client_read);
	UNSET_FLAG(flag_discovered);
	UNSET_FLAG(flag_sc_indicated);
	UNSET_FLAG(flag_sc_subscribed);
	UNSET_FLAG(flag_written);
	UNSET_FLAG(flag_read);
}
