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

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/audio/tmap.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>
#include <zephyr/sys/util_macro.h>
#include <zephyr/types.h>

#include "audio_internal.h"

LOG_MODULE_REGISTER(bt_tmap, CONFIG_BT_TMAP_LOG_LEVEL);

/* Hex value if all TMAP role bits are set */
#define TMAP_ALL_ROLES                                                                             \
	(BT_TMAP_ROLE_CG | BT_TMAP_ROLE_CT | BT_TMAP_ROLE_UMS | BT_TMAP_ROLE_UMR |                 \
	 BT_TMAP_ROLE_BMS | BT_TMAP_ROLE_BMR)

static uint16_t tmap_role;
static const 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 of 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) {
			LOG_DBG("Could not read peer TMAP Role");
		}
	} 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_GATT_CHARACTERISTIC(BT_UUID_GATT_TMAPR, \
			       BT_GATT_CHRC_READ, \
			       BT_GATT_PERM_READ, \
			       read_role, NULL, NULL)

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

static bool valid_tmap_role(enum bt_tmap_role role)
{
	if (role == 0 || (role & TMAP_ALL_ROLES) != role) {
		LOG_DBG("Invalid role %d", role);
	}

	if ((role & BT_TMAP_ROLE_CG) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_CG_SUPPORTED)) {
		LOG_DBG("Device does not support the CG role");

		return false;
	}

	if ((role & BT_TMAP_ROLE_CT) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_CT_SUPPORTED)) {
		LOG_DBG("Device does not support the CT role");

		return false;
	}

	if ((role & BT_TMAP_ROLE_UMS) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_UMS_SUPPORTED)) {
		LOG_DBG("Device does not support the UMS role");

		return false;
	}

	if ((role & BT_TMAP_ROLE_UMR) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_UMR_SUPPORTED)) {
		LOG_DBG("Device does not support the UMR role");

		return false;
	}

	if ((role & BT_TMAP_ROLE_BMS) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_BMS_SUPPORTED)) {
		LOG_DBG("Device does not support the BMS role");

		return false;
	}

	if ((role & BT_TMAP_ROLE_BMR) != 0 && !IS_ENABLED(CONFIG_BT_TMAP_BMR_SUPPORTED)) {
		LOG_DBG("Device does not support the BMR role");

		return false;
	}

	return true;
}

int bt_tmap_register(enum bt_tmap_role role)
{
	int err;

	CHECKIF(!valid_tmap_role(role)) {
		LOG_DBG("Invalid role: %d", role);

		return -EINVAL;
	}

	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, const 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;
}
