/*
 * Copyright 2023 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr/device.h>
#include <zephyr/init.h>
#include <stdlib.h>

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

#include "audio_internal.h"
#include <zephyr/bluetooth/audio/tmap.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_tmap, CONFIG_BT_TMAP_LOG_LEVEL);

/* Hex value if all TMAP role bits are set */
#define TMAP_ALL_ROLES		0x3F

static uint16_t tmap_role;
static struct bt_tmap_cb *cb;
static bool tmas_found;

static struct bt_uuid_16 uuid[CONFIG_BT_MAX_CONN] = {BT_UUID_INIT_16(0)};
static struct bt_gatt_discover_params discover_params[CONFIG_BT_MAX_CONN];
static struct bt_gatt_read_params read_params[CONFIG_BT_MAX_CONN];

uint8_t tmap_char_read(struct bt_conn *conn, uint8_t err,
		       struct bt_gatt_read_params *params,
		       const void *data, uint16_t length)
{
	uint16_t peer_role;

	/* Check read request result */
	if (err != BT_ATT_ERR_SUCCESS) {
		if (cb->discovery_complete) {
			cb->discovery_complete(0, conn, err);
		}

		return BT_GATT_ITER_STOP;
	}

	/* Check data length */
	if (length != sizeof(peer_role)) {
		if (cb->discovery_complete) {
			cb->discovery_complete(0, conn, BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		return BT_GATT_ITER_STOP;
	}

	/* Extract the TMAP role of the peer and inform application fo the value found */
	peer_role = sys_get_le16(data);

	if ((peer_role > 0U) && (peer_role <= TMAP_ALL_ROLES)) {
		if (cb->discovery_complete) {
			cb->discovery_complete((enum bt_tmap_role)peer_role, conn, 0);
		}
	} else {
		if (cb->discovery_complete) {
			cb->discovery_complete(0, conn, BT_ATT_ERR_VALUE_NOT_ALLOWED);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	int err;
	uint8_t conn_id = bt_conn_index(conn);

	if (!attr) {
		(void)memset(params, 0, sizeof(*params));
		if (!tmas_found) {
			/* TMAS not found on peer */
			if (cb->discovery_complete) {
				cb->discovery_complete(0, conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
			}
		}

		tmas_found = false;

		return BT_GATT_ITER_STOP;
	}

	if (!bt_uuid_cmp(discover_params[conn_id].uuid, BT_UUID_TMAS)) {
		LOG_DBG("Discovered TMAS\n");
		tmas_found = true;
		memcpy(&uuid[conn_id], BT_UUID_GATT_TMAPR, sizeof(uuid[conn_id]));
		discover_params[conn_id].uuid = &uuid[conn_id].uuid;
		discover_params[conn_id].start_handle = attr->handle + 1;
		discover_params[conn_id].type = BT_GATT_DISCOVER_CHARACTERISTIC;

		/* Discovered TMAS - Search for TMAP Role characteristic */
		err = bt_gatt_discover(conn, &discover_params[conn_id]);
		if (err) {
			LOG_DBG("Discover failed (err %d)\n", err);
		}
	} else if (!bt_uuid_cmp(discover_params[conn_id].uuid, BT_UUID_GATT_TMAPR)) {
		/* Use 0 for now, will expand later */
		read_params[conn_id].func = tmap_char_read;
		read_params[conn_id].handle_count = 1u;
		read_params[conn_id].single.handle = bt_gatt_attr_value_handle(attr);
		read_params[conn_id].single.offset = 0;

		/* Discovered TMAP Role characteristic - read value */
		err = bt_gatt_read(conn, &read_params[0]);
		if (err != 0) {
			printk("Could not read peer TMAP Role\n");
		}
	} else {
		return BT_GATT_ITER_CONTINUE;
	}

	return BT_GATT_ITER_STOP;
}

static ssize_t read_role(struct bt_conn *conn,
			 const struct bt_gatt_attr *attr, void *buf,
			 uint16_t len, uint16_t offset)
{
	uint16_t role;

	role = sys_cpu_to_le16(tmap_role);
	LOG_DBG("TMAP: role 0x%04X", role);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &role, sizeof(role));
}

/* Telephony and Media Audio Service attributes */
#define BT_TMAS_SERVICE_DEFINITION \
	BT_GATT_PRIMARY_SERVICE(BT_UUID_TMAS), \
	BT_AUDIO_CHRC(BT_UUID_GATT_TMAPR, \
		      BT_GATT_CHRC_READ, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_role, NULL, NULL)

static struct bt_gatt_attr svc_attrs[] = { BT_TMAS_SERVICE_DEFINITION };
static struct bt_gatt_service tmas;

int bt_tmap_register(enum bt_tmap_role role)
{
	int err;

	tmas = (struct bt_gatt_service)BT_GATT_SERVICE(svc_attrs);

	err = bt_gatt_service_register(&tmas);
	if (err) {
		LOG_DBG("Could not register the TMAS service");
		return -ENOEXEC;
	}

	tmap_role = role;
	tmas_found = false;

	return 0;
}

int bt_tmap_discover(struct bt_conn *conn, struct bt_tmap_cb *tmap_cb)
{
	int err = 0;
	uint8_t conn_id = bt_conn_index(conn);

	cb = tmap_cb;

	memcpy(&uuid[conn_id], BT_UUID_TMAS, sizeof(uuid[conn_id]));
	discover_params[conn_id].uuid = &uuid[conn_id].uuid;
	discover_params[conn_id].func = discover_func;
	discover_params[conn_id].start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params[conn_id].end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	discover_params[conn_id].type = BT_GATT_DISCOVER_PRIMARY;

	err = bt_gatt_discover(conn, &discover_params[conn_id]);

	return err;
}

void bt_tmap_set_role(enum bt_tmap_role role)
{
	tmap_role = role;
}
