/*  Bluetooth MICP - Microphone Input Control Profile - Microphone Controller */

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

#include <zephyr/zephyr.h>
#include <zephyr/types.h>

#include <zephyr/sys/check.h>

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

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

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_MICP_MIC_CTLR)
#define LOG_MODULE_NAME bt_micp_mic_ctlr
#include "common/log.h"

/* Callback functions */
static struct bt_micp_mic_ctlr_cb *micp_mic_ctlr_cb;

struct bt_micp_mic_ctlr {
	uint16_t start_handle;
	uint16_t end_handle;
	uint16_t mute_handle;
	struct bt_gatt_subscribe_params mute_sub_params;
	struct bt_gatt_discover_params mute_sub_disc_params;

	bool busy;
	uint8_t mute_val_buf[1]; /* Mute value is a single octet */
	struct bt_gatt_write_params write_params;
	struct bt_gatt_read_params read_params;
	struct bt_gatt_discover_params discover_params;
	struct bt_conn *conn;

	uint8_t aics_inst_cnt;
	struct bt_aics *aics[CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST];
};

static struct bt_micp_mic_ctlr mic_ctlrs[CONFIG_BT_MAX_CONN];
static struct bt_uuid *mics_uuid = BT_UUID_MICS;

static uint8_t mute_notify_handler(struct bt_conn *conn,
				   struct bt_gatt_subscribe_params *params,
				   const void *data, uint16_t length)
{
	uint8_t *mute_val;
	struct bt_micp_mic_ctlr *mic_ctlr;

	if (conn == NULL) {
		return BT_GATT_ITER_CONTINUE;
	}

	mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	if (data != NULL) {
		if (length == sizeof(*mute_val)) {
			mute_val = (uint8_t *)data;
			BT_DBG("Mute %u", *mute_val);
			if (micp_mic_ctlr_cb != NULL &&
			    micp_mic_ctlr_cb->mute != NULL) {
				micp_mic_ctlr_cb->mute(mic_ctlr, 0, *mute_val);
			}
		} else {
			BT_DBG("Invalid length %u (expected %zu)",
			       length, sizeof(*mute_val));

		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t micp_mic_ctlr_read_mute_cb(struct bt_conn *conn, uint8_t err,
					struct bt_gatt_read_params *params,
					const void *data, uint16_t length)
{
	uint8_t cb_err = err;
	uint8_t mute_val = 0;
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	mic_ctlr->busy = false;

	if (err > 0) {
		BT_DBG("err: 0x%02X", err);
	} else if (data != NULL) {
		if (length == sizeof(mute_val)) {
			mute_val = ((uint8_t *)data)[0];
			BT_DBG("Mute %u", mute_val);
		} else {
			BT_DBG("Invalid length %u (expected %zu)",
			       length, sizeof(mute_val));
			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (micp_mic_ctlr_cb != NULL && micp_mic_ctlr_cb->mute != NULL) {
		micp_mic_ctlr_cb->mute(mic_ctlr, cb_err, mute_val);
	}

	return BT_GATT_ITER_STOP;
}

static void micp_mic_ctlr_write_mics_mute_cb(struct bt_conn *conn, uint8_t err,
					   struct bt_gatt_write_params *params)
{
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];
	uint8_t mute_val = mic_ctlr->mute_val_buf[0];

	BT_DBG("Write %s (0x%02X)", err ? "failed" : "successful", err);

	mic_ctlr->busy = false;

	if (mute_val == BT_MICP_MUTE_UNMUTED) {
		if (micp_mic_ctlr_cb != NULL &&
		    micp_mic_ctlr_cb->unmute_written != NULL) {
			micp_mic_ctlr_cb->unmute_written(mic_ctlr, err);
		}

	} else {
		if (micp_mic_ctlr_cb != NULL &&
		    micp_mic_ctlr_cb->mute_written != NULL) {
			micp_mic_ctlr_cb->mute_written(mic_ctlr, err);
		}
	}
}

#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
static struct bt_micp_mic_ctlr *lookup_micp_by_aics(const struct bt_aics *aics)
{
	__ASSERT(aics != NULL, "AICS pointer cannot be NULL");

	for (int i = 0; i < ARRAY_SIZE(mic_ctlrs); i++) {
		for (int j = 0; j < ARRAY_SIZE(mic_ctlrs[i].aics); j++) {
			if (mic_ctlrs[i].aics[j] == aics) {
				return &mic_ctlrs[i];
			}
		}
	}

	return NULL;
}

static void aics_discover_cb(struct bt_aics *inst, int err)
{
	struct bt_micp_mic_ctlr *mic_ctlr = lookup_micp_by_aics(inst);

	if (err == 0) {
		/* Continue discovery of included services */
		err = bt_gatt_discover(mic_ctlr->conn,
				       &mic_ctlr->discover_params);
	}

	if (err != 0) {
		BT_DBG("Discover failed (err %d)", err);
		if (micp_mic_ctlr_cb != NULL &&
		    micp_mic_ctlr_cb->discover != NULL) {
			micp_mic_ctlr_cb->discover(mic_ctlr, err, 0);
		}
	}
}
#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */

static uint8_t micp_discover_include_func(
	struct bt_conn *conn, const struct bt_gatt_attr *attr,
	struct bt_gatt_discover_params *params)
{
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	if (attr == NULL) {
		BT_DBG("Discover include complete for MICS: %u AICS",
		       mic_ctlr->aics_inst_cnt);
		(void)memset(params, 0, sizeof(*params));

		if (micp_mic_ctlr_cb != NULL &&
		    micp_mic_ctlr_cb->discover != NULL) {
			micp_mic_ctlr_cb->discover(mic_ctlr, 0,
						   mic_ctlr->aics_inst_cnt);
		}

		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_INCLUDE) {
		struct bt_gatt_include *include = (struct bt_gatt_include *)attr->user_data;

		BT_DBG("Include UUID %s", bt_uuid_str(include->uuid));

		if (bt_uuid_cmp(include->uuid, BT_UUID_AICS) == 0 &&
		    mic_ctlr->aics_inst_cnt < CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST) {
			uint8_t inst_idx;
			int err;
			struct bt_aics_discover_param param = {
				.start_handle = include->start_handle,
				.end_handle = include->end_handle,
			};

			/* Update discover params so we can continue where we
			 * left off after bt_aics_discover
			 */
			mic_ctlr->discover_params.start_handle = attr->handle + 1;

			inst_idx = mic_ctlr->aics_inst_cnt++;
			err = bt_aics_discover(conn, mic_ctlr->aics[inst_idx],
					       &param);
			if (err != 0) {
				BT_DBG("AICS Discover failed (err %d)", err);
				if (micp_mic_ctlr_cb != NULL &&
				    micp_mic_ctlr_cb->discover != NULL) {
					micp_mic_ctlr_cb->discover(mic_ctlr, err,
								 0);
				}
			}
			return BT_GATT_ITER_STOP;
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t micp_discover_func(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  struct bt_gatt_discover_params *params)
{
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	if (attr == NULL) {
		int err = 0;

		BT_DBG("Discovery complete");
		(void)memset(params, 0, sizeof(*params));
		if (CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST > 0) {
			/* Discover included services */
			mic_ctlr->discover_params.start_handle = mic_ctlr->start_handle;
			mic_ctlr->discover_params.end_handle = mic_ctlr->end_handle;
			mic_ctlr->discover_params.type = BT_GATT_DISCOVER_INCLUDE;
			mic_ctlr->discover_params.func = micp_discover_include_func;

			err = bt_gatt_discover(conn,
					       &mic_ctlr->discover_params);
			if (err != 0) {
				BT_DBG("Discover AICS failed (err %d)", err);
				if (micp_mic_ctlr_cb != NULL &&
				    micp_mic_ctlr_cb->discover != NULL) {
					micp_mic_ctlr_cb->discover(mic_ctlr, err, 0);
				}
			}
		} else {
			if (micp_mic_ctlr_cb != NULL &&
			    micp_mic_ctlr_cb->discover != NULL) {
				micp_mic_ctlr_cb->discover(mic_ctlr, err, 0);
			}
		}
		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

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

		if (bt_uuid_cmp(chrc->uuid, BT_UUID_MICS_MUTE) == 0) {
			BT_DBG("Mute");
			mic_ctlr->mute_handle = chrc->value_handle;
			sub_params = &mic_ctlr->mute_sub_params;
			sub_params->disc_params = &mic_ctlr->mute_sub_disc_params;
		}

		if (sub_params != NULL) {
			int err;

			/* With ccc_handle == 0 it will use auto discovery */
			sub_params->ccc_handle = 0;
			sub_params->end_handle = mic_ctlr->end_handle;
			sub_params->value = BT_GATT_CCC_NOTIFY;
			sub_params->value_handle = chrc->value_handle;
			sub_params->notify = mute_notify_handler;

			err = bt_gatt_subscribe(conn, sub_params);
			if (err == 0) {
				BT_DBG("Subscribed to handle 0x%04X",
				       attr->handle);
			} else {
				BT_DBG("Could not subscribe to handle 0x%04X: %d",
				       attr->handle, err);
			}
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t primary_discover_func(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     struct bt_gatt_discover_params *params)
{
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	if (attr == NULL) {
		BT_DBG("Could not find a MICS instance on the server");
		if (micp_mic_ctlr_cb != NULL &&
		    micp_mic_ctlr_cb->discover != NULL) {
			micp_mic_ctlr_cb->discover(mic_ctlr, -ENODATA, 0);
		}
		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		struct bt_gatt_service_val *prim_service =
			(struct bt_gatt_service_val *)attr->user_data;
		int err;

		BT_DBG("Primary discover complete");
		mic_ctlr->start_handle = attr->handle + 1;
		mic_ctlr->end_handle = prim_service->end_handle;

		/* Discover characteristics */
		mic_ctlr->discover_params.uuid = NULL;
		mic_ctlr->discover_params.start_handle = mic_ctlr->start_handle;
		mic_ctlr->discover_params.end_handle = mic_ctlr->end_handle;
		mic_ctlr->discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
		mic_ctlr->discover_params.func = micp_discover_func;

		err = bt_gatt_discover(conn, &mic_ctlr->discover_params);
		if (err != 0) {
			BT_DBG("Discover failed (err %d)", err);
			if (micp_mic_ctlr_cb != NULL &&
			    micp_mic_ctlr_cb->discover != NULL) {
				micp_mic_ctlr_cb->discover(mic_ctlr, err, 0);
			}
		}

		return BT_GATT_ITER_STOP;
	}

	return BT_GATT_ITER_CONTINUE;
}

static void micp_mic_ctlr_reset(struct bt_micp_mic_ctlr *mic_ctlr)
{
	mic_ctlr->start_handle = 0;
	mic_ctlr->end_handle = 0;
	mic_ctlr->mute_handle = 0;
	mic_ctlr->aics_inst_cnt = 0;

	if (mic_ctlr->conn != NULL) {
		struct bt_conn *conn = mic_ctlr->conn;

		/* It's okay if this fails. In case of disconnect, we can't
		 * unsubscribe and it will just fail.
		 * In case that we reset due to another call of the discover
		 * function, we will unsubscribe (regardless of bonding state)
		 * to accommodate the new discovery values.
		 */
		(void)bt_gatt_unsubscribe(conn, &mic_ctlr->mute_sub_params);

		bt_conn_unref(conn);
		mic_ctlr->conn = NULL;
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	struct bt_micp_mic_ctlr *mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	if (mic_ctlr->conn == conn) {
		micp_mic_ctlr_reset(mic_ctlr);
	}
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.disconnected = disconnected,
};

int bt_micp_mic_ctlr_discover(struct bt_conn *conn, struct bt_micp_mic_ctlr **mic_ctlr_out)
{
	struct bt_micp_mic_ctlr *mic_ctlr;
	int err;

	/*
	 * This will initiate a discover procedure. The procedure will do the
	 * following sequence:
	 * 1) Primary discover for the MICS
	 * 2) Characteristic discover of the MICS
	 * 3) Discover services included in MICS (AICS)
	 * 4) For each included service found; discovery of the characteristics
	 * 5) When everything above have been discovered, the callback is called
	 */

	CHECKIF(conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	mic_ctlr = &mic_ctlrs[bt_conn_index(conn)];

	(void)memset(&mic_ctlr->discover_params, 0,
		     sizeof(mic_ctlr->discover_params));
	micp_mic_ctlr_reset(mic_ctlr);

#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
	static bool initialized;

	if (!initialized) {
		for (int i = 0; i < ARRAY_SIZE(mic_ctlr->aics); i++) {
			mic_ctlr->aics[i] = bt_aics_client_free_instance_get();

			if (mic_ctlr->aics[i] == NULL) {
				return -ENOMEM;
			}

			bt_aics_client_cb_register(mic_ctlr->aics[i],
						   &micp_mic_ctlr_cb->aics_cb);
		}
	}

	initialized = true;
#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */

	mic_ctlr->conn = bt_conn_ref(conn);
	mic_ctlr->discover_params.func = primary_discover_func;
	mic_ctlr->discover_params.uuid = mics_uuid;
	mic_ctlr->discover_params.type = BT_GATT_DISCOVER_PRIMARY;
	mic_ctlr->discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	mic_ctlr->discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	err = bt_gatt_discover(conn, &mic_ctlr->discover_params);
	if (err == 0) {
		*mic_ctlr_out = mic_ctlr;
	}

	return err;
}

int bt_micp_mic_ctlr_cb_register(struct bt_micp_mic_ctlr_cb *cb)
{
#if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
	struct bt_aics_cb *aics_cb = NULL;

	if (cb != NULL) {
		CHECKIF(cb->aics_cb.discover != NULL) {
			BT_ERR("AICS discover callback shall not be set");
			return -EINVAL;
		}
		cb->aics_cb.discover = aics_discover_cb;

		aics_cb = &cb->aics_cb;
	}

	for (int i = 0; i < ARRAY_SIZE(mic_ctlrs); i++) {
		for (int j = 0; j < ARRAY_SIZE(mic_ctlrs[i].aics); j++) {
			struct bt_aics *aics = mic_ctlrs[i].aics[j];

			if (aics != NULL) {
				bt_aics_client_cb_register(aics, aics_cb);
			}
		}
	}
#endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */

	micp_mic_ctlr_cb = cb;

	return 0;
}

int bt_micp_mic_ctlr_included_get(struct bt_micp_mic_ctlr *mic_ctlr,
				  struct bt_micp_included *included)
{
	CHECKIF(mic_ctlr == NULL) {
		BT_DBG("NULL mic_ctlr");
		return -EINVAL;
	}

	CHECKIF(included == NULL) {
		return -EINVAL;
	}

	included->aics_cnt = mic_ctlr->aics_inst_cnt;
	included->aics = mic_ctlr->aics;

	return 0;
}

int bt_micp_mic_ctlr_conn_get(const struct bt_micp_mic_ctlr *mic_ctlr, struct bt_conn **conn)
{
	CHECKIF(mic_ctlr == NULL) {
		BT_DBG("NULL mic_ctlr pointer");
		return -EINVAL;
	}

	if (mic_ctlr->conn == NULL) {
		BT_DBG("mic_ctlr pointer not associated with a connection. "
		       "Do discovery first");
		return -ENOTCONN;
	}

	*conn = mic_ctlr->conn;
	return 0;
}

int bt_micp_mic_ctlr_mute_get(struct bt_micp_mic_ctlr *mic_ctlr)
{
	int err;

	CHECKIF(mic_ctlr == NULL) {
		BT_DBG("NULL mic_ctlr");
		return -EINVAL;
	}

	if (mic_ctlr->mute_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (mic_ctlr->busy) {
		return -EBUSY;
	}

	mic_ctlr->read_params.func = micp_mic_ctlr_read_mute_cb;
	mic_ctlr->read_params.handle_count = 1;
	mic_ctlr->read_params.single.handle = mic_ctlr->mute_handle;
	mic_ctlr->read_params.single.offset = 0U;

	err = bt_gatt_read(mic_ctlr->conn, &mic_ctlr->read_params);
	if (err == 0) {
		mic_ctlr->busy = true;
	}

	return err;
}

int bt_micp_mic_ctlr_write_mute(struct bt_micp_mic_ctlr *mic_ctlr, bool mute)
{
	int err;

	CHECKIF(mic_ctlr == NULL) {
		BT_DBG("NULL mic_ctlr");
		return -EINVAL;
	}

	if (mic_ctlr->mute_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (mic_ctlr->busy) {
		return -EBUSY;
	}

	mic_ctlr->mute_val_buf[0] = mute;
	mic_ctlr->write_params.offset = 0;
	mic_ctlr->write_params.data = mic_ctlr->mute_val_buf;
	mic_ctlr->write_params.length = sizeof(mute);
	mic_ctlr->write_params.handle = mic_ctlr->mute_handle;
	mic_ctlr->write_params.func = micp_mic_ctlr_write_mics_mute_cb;

	err = bt_gatt_write(mic_ctlr->conn, &mic_ctlr->write_params);
	if (err == 0) {
		mic_ctlr->busy = true;
	}

	return err;
}

int bt_micp_mic_ctlr_mute(struct bt_micp_mic_ctlr *mic_ctlr)
{
	return bt_micp_mic_ctlr_write_mute(mic_ctlr, true);
}

int bt_micp_mic_ctlr_unmute(struct bt_micp_mic_ctlr *mic_ctlr)
{
	return bt_micp_mic_ctlr_write_mute(mic_ctlr, false);
}
