/* @file
 * @brief Bluetooth PACS
 */

/*
 * Copyright (c) 2020 Intel Corporation
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <device.h>
#include <init.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>
#include <bluetooth/audio/audio.h>
#include <bluetooth/audio/capabilities.h>
#include "../host/conn_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_PACS)
#define LOG_MODULE_NAME bt_pacs
#include "common/log.h"

#include "pacs_internal.h"
#include "unicast_server.h"

#define PAC_NOTIFY_TIMEOUT	K_MSEC(10)

#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, CONFIG_BT_L2CAP_TX_MTU);

static void pac_data_add(struct net_buf_simple *buf, uint8_t num,
			 struct bt_codec_data *data)
{
	struct bt_pac_codec_capability *cc;
	int i;

	for (i = 0; i < num; i++) {
		struct bt_data *d = &data[i].data;

		cc = net_buf_simple_add(buf, sizeof(*cc));
		cc->len = d->data_len + sizeof(cc->type);
		cc->type = d->type;
		net_buf_simple_add_mem(buf, d->data, d->data_len);
	}
}

static void get_pac_records(struct bt_conn *conn, uint8_t type,
			    struct net_buf_simple *buf)
{
	struct bt_pacs_read_rsp *rsp;

	/* Reset if buffer before using */
	net_buf_simple_reset(buf);

	rsp = net_buf_simple_add(&read_buf, sizeof(*rsp));
	rsp->num_pac = 0;

	if (unicast_server_cb == NULL ||
	    unicast_server_cb->publish_capability == NULL) {
		return;
	}

	while (true) {
		struct bt_pac_meta *meta;
		struct bt_codec codec;
		struct bt_pac *pac;
		int err;

		err = unicast_server_cb->publish_capability(conn, type,
							    rsp->num_pac,
							    &codec);
		if (err != 0) {
			break;
		}

		pac = net_buf_simple_add(&read_buf, sizeof(*pac));

		pac->codec.id = codec.id;
		pac->codec.cid = sys_cpu_to_le16(codec.cid);
		pac->codec.vid = sys_cpu_to_le16(codec.vid);
		pac->cc_len = read_buf.len;

		pac_data_add(&read_buf, codec.data_count, codec.data);

		/* Buffer size shall never be below PAC len since we are just
		 * append data.
		 */
		__ASSERT_NO_MSG(read_buf.len >= pac->cc_len);

		pac->cc_len = read_buf.len - pac->cc_len;

		meta = net_buf_simple_add(&read_buf, sizeof(*meta));
		meta->len = read_buf.len;
		pac_data_add(&read_buf, codec.meta_count, codec.meta);
		meta->len = read_buf.len - meta->len;

		BT_DBG("pac #%u: codec capability len %u metadata len %u",
		       rsp->num_pac, pac->cc_len, meta->len);

		rsp->num_pac++;
	}
}

static ssize_t pac_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			void *buf, uint16_t len, uint16_t offset)
{
	uint8_t type;

	if (!bt_uuid_cmp(attr->uuid, BT_UUID_PACS_SNK)) {
		type = BT_AUDIO_SINK;
	} else {
		type = BT_AUDIO_SOURCE;
	}

	get_pac_records(conn, type, &read_buf);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data,
				 read_buf.len);
}

static void context_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}

static ssize_t context_read(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr, void *buf,
			    uint16_t len, uint16_t offset)
{
	struct bt_pacs_context context = {
		/* TODO: This should reflect the ongoing channel contexts */
		.snk = 0x0001,
		.src = 0x0001,
	};

	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

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

static void supported_context_cfg_changed(const struct bt_gatt_attr *attr,
					  uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}

static ssize_t supported_context_read(struct bt_conn *conn,
				      const struct bt_gatt_attr *attr,
				      void *buf, uint16_t len, uint16_t offset)
{
	struct bt_pacs_context context = {
#if defined(CONFIG_BT_PAC_SNK)
		.snk = sys_cpu_to_le16(CONFIG_BT_PACS_SNK_CONTEXT),
#endif
#if defined(CONFIG_BT_PAC_SRC)
		.src = sys_cpu_to_le16(CONFIG_BT_PACS_SRC_CONTEXT),
#endif
	};

	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

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

static int get_pac_loc(struct bt_conn *conn, enum bt_audio_pac_type type,
		       enum bt_audio_location *location)
{
	int err;

	if (unicast_server_cb == NULL ||
	    unicast_server_cb->publish_location == NULL) {
		BT_WARN("No callback for publish_location");
		return -ENODATA;
	}

	err = unicast_server_cb->publish_location(conn, type, location);
	if (err != 0 || *location == 0) {
		BT_DBG("err (%d) or invalid location value (%u)",
		       err, *location);
		return -ENODATA;
	}

	return 0;
}
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */

#if defined(CONFIG_BT_PAC_SNK)
static struct k_work_delayable snks_work;
static struct k_work_delayable snks_loc_work;

static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			void *buf, uint16_t len, uint16_t offset)
{
	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

	return pac_read(conn, attr, buf, len, offset);
}

static ssize_t snk_loc_read(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr, void *buf,
			    uint16_t len, uint16_t offset)
{
	int err;
	enum bt_audio_location location;
	uint32_t location_32;
	uint32_t location_32_le;

	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

	err = get_pac_loc(NULL, BT_AUDIO_SINK, &location);
	if (err != 0) {
		BT_DBG("get_pac_loc returned %d", err);
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location_32 = (uint32_t)location;
	if (location_32 > BT_AUDIO_LOCATION_MASK || location_32 == 0) {
		BT_ERR("Invalid location value: 0x%08X", location_32);
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location_32_le = sys_cpu_to_le32(location_32);

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

static ssize_t snk_loc_write(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr, const void *data,
			     uint16_t len, uint16_t offset, uint8_t flags)
{
	int err;
	enum bt_audio_location location;

	if (offset) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (len != sizeof(location)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	if (unicast_server_cb == NULL ||
	    unicast_server_cb->write_location == NULL) {
		BT_WARN("No callback for write_location");
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location = (enum bt_audio_location)sys_get_le32(data);
	if (location > BT_AUDIO_LOCATION_MASK || location == 0) {
		BT_DBG("Invalid location value: 0x%08X", location);
		return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
	}

	err = unicast_server_cb->write_location(conn, BT_AUDIO_SINK, location);
	if (err != 0) {
		BT_DBG("write_location returned %d", err);
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	return len;
}

static void snk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}

static void snk_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}
#endif /* CONFIG_BT_PAC_SNK */

#if defined(CONFIG_BT_PAC_SRC)
static struct k_work_delayable srcs_work;
static struct k_work_delayable srcs_loc_work;

static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			void *buf, uint16_t len, uint16_t offset)
{
	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

	return pac_read(conn, attr, buf, len, offset);
}

static ssize_t src_loc_read(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr, void *buf,
			    uint16_t len, uint16_t offset)
{
	int err;
	enum bt_audio_location location;
	uint32_t location_32;
	uint32_t location_32_le;

	BT_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len,
	       offset);

	err = get_pac_loc(NULL, BT_AUDIO_SOURCE, &location);
	if (err != 0) {
		BT_DBG("get_pac_loc returned %d", err);
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location_32 = (uint32_t)location;
	if (location_32 > BT_AUDIO_LOCATION_MASK || location_32 == 0) {
		BT_ERR("Invalid location value: 0x%08X", location_32);
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location_32_le = sys_cpu_to_le32(location_32);

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

static ssize_t src_loc_write(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr, const void *data,
			     uint16_t len, uint16_t offset, uint8_t flags)
{
	int err;
	uint32_t location;

	if (offset) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (len != sizeof(location)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	if (unicast_server_cb == NULL ||
	    unicast_server_cb->write_location == NULL) {
		BT_WARN("No callback for write_location");
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	location = (enum bt_audio_location)sys_get_le32(data);
	if (location > BT_AUDIO_LOCATION_MASK || location == 0) {
		BT_DBG("Invalid location value: 0x%08X", location);
		return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
	}

	err = unicast_server_cb->write_location(conn, BT_AUDIO_SOURCE,
						location);
	if (err != 0) {
		BT_DBG("write_location returned %d", err);
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	return len;
}

static void src_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}

static void src_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	BT_DBG("attr %p value 0x%04x", attr, value);
}
#endif /* CONFIG_BT_PAC_SRC */

#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
BT_GATT_SERVICE_DEFINE(pacs_svc,
	BT_GATT_PRIMARY_SERVICE(BT_UUID_PACS),
#if defined(CONFIG_BT_PAC_SNK)
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT,
			       snk_read, NULL, NULL),
	BT_GATT_CCC(snk_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SNK_LOC,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
			       BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT |
			       BT_GATT_PERM_WRITE_ENCRYPT,
			       snk_loc_read, snk_loc_write, NULL),
	BT_GATT_CCC(snk_loc_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC)
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT,
			       src_read, NULL, NULL),
	BT_GATT_CCC(src_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SRC_LOC,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
			       BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT |
			       BT_GATT_PERM_WRITE_ENCRYPT,
			       src_loc_read, src_loc_write, NULL),
	BT_GATT_CCC(src_loc_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
#endif /* CONFIG_BT_PAC_SNK */
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_CONTEXT,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT,
			       context_read, NULL, NULL),
	BT_GATT_CCC(context_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
	BT_GATT_CHARACTERISTIC(BT_UUID_PACS_SUPPORTED_CONTEXT,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
			       BT_GATT_PERM_READ_ENCRYPT,
			       supported_context_read, NULL, NULL),
	BT_GATT_CCC(supported_context_cfg_changed,
		    BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT)
);
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */

static struct k_work_delayable *bt_pacs_get_work(uint8_t type)
{
	switch (type) {
#if defined(CONFIG_BT_PAC_SNK)
	case BT_AUDIO_SINK:
		return &snks_work;
#endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC)
	case BT_AUDIO_SOURCE:
		return &srcs_work;
#endif /* CONFIG_BT_PAC_SNK */
	}

	return NULL;
}

static struct k_work_delayable *bt_pacs_get_loc_work(uint8_t type)
{
	switch (type) {
#if defined(CONFIG_BT_PAC_SNK)
	case BT_AUDIO_SINK:
		return &snks_loc_work;
#endif /* CONFIG_BT_PAC_SNK */
#if defined(CONFIG_BT_PAC_SRC)
	case BT_AUDIO_SOURCE:
		return &srcs_loc_work;
#endif /* CONFIG_BT_PAC_SNK */
	}

	return NULL;
}

static void pac_notify(struct k_work *work)
{
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
	struct bt_uuid *uuid;
	uint8_t type;
	int err;

#if defined(CONFIG_BT_PAC_SNK)
	if (work == &snks_work.work) {
		type = BT_AUDIO_SINK;
		uuid = BT_UUID_PACS_SNK;
	}
#endif /* CONFIG_BT_PAC_SNK */

#if defined(CONFIG_BT_PAC_SRC)
	if (work == &srcs_work.work) {
		type = BT_AUDIO_SOURCE;
		uuid = BT_UUID_PACS_SRC;
	}
#endif /* CONFIG_BT_PAC_SRC */

	/* TODO: We can skip this if we are not connected to any devices */
	get_pac_records(NULL, type, &read_buf);

	err = bt_gatt_notify_uuid(NULL, uuid, pacs_svc.attrs, read_buf.data,
				  read_buf.len);
	if (err != 0) {
		BT_WARN("PACS notify failed: %d", err);
	}
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
}

static void pac_notify_loc(struct k_work *work)
{
#if defined(CONFIG_BT_PAC_SNK) || defined(CONFIG_BT_PAC_SRC)
	uint32_t location;
	struct bt_uuid *uuid;
	enum bt_audio_pac_type type;
	int err;

#if defined(CONFIG_BT_PAC_SNK)
	if (work == &snks_loc_work.work) {
		type = BT_AUDIO_SINK;
		uuid = BT_UUID_PACS_SNK_LOC;
	}
#endif /* CONFIG_BT_PAC_SNK */

#if defined(CONFIG_BT_PAC_SRC)
	if (work == &srcs_loc_work.work) {
		type = BT_AUDIO_SOURCE;
		uuid = BT_UUID_PACS_SRC_LOC;
	}
#endif /* CONFIG_BT_PAC_SRC */

	/* TODO: We can skip this if we are not connected to any devices */
	err = get_pac_loc(NULL, type, &location);
	if (err != 0) {
		BT_DBG("get_pac_loc returned %d, won't notify", err);
		return;
	}

	err = bt_gatt_notify_uuid(NULL, uuid, pacs_svc.attrs,
				  &sys_cpu_to_le32(location),
				  sizeof(location));
	if (err != 0) {
		BT_WARN("PACS notify failed: %d", err);
	}
#endif /* CONFIG_BT_PAC_SNK || CONFIG_BT_PAC_SRC */
}

void bt_pacs_add_capability(uint8_t type)
{
	struct k_work_delayable *work;

	work = bt_pacs_get_work(type);
	if (!work) {
		return;
	}

	/* Initialize handler if it hasn't been initialized */
	if (!work->work.handler) {
		k_work_init_delayable(work, pac_notify);
	}

	k_work_reschedule(work, PAC_NOTIFY_TIMEOUT);
}

void bt_pacs_remove_capability(uint8_t type)
{
	struct k_work_delayable *work;

	work = bt_pacs_get_work(type);
	if (!work) {
		return;
	}

	k_work_reschedule(work, PAC_NOTIFY_TIMEOUT);
}

int bt_pacs_location_changed(enum bt_audio_pac_type type)
{
	struct k_work_delayable *work;

	work = bt_pacs_get_loc_work(type);
	if (!work) {
		return -EINVAL;
	}

	/* Initialize handler if it hasn't been initialized */
	if (!work->work.handler) {
		k_work_init_delayable(work, pac_notify_loc);
	}

	k_work_reschedule(work, PAC_NOTIFY_TIMEOUT);

	return 0;
}
