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

#include <zephyr/logging/log.h>
#include <zephyr/sys/check.h>

#include "cap_internal.h"
#include "csip_internal.h"

LOG_MODULE_REGISTER(bt_cap_common, CONFIG_BT_CAP_COMMON_LOG_LEVEL);

#include "common/bt_str.h"

static struct bt_cap_common_client bt_cap_common_clients[CONFIG_BT_MAX_CONN];
static const struct bt_uuid *cas_uuid = BT_UUID_CAS;
static struct bt_cap_common_proc active_proc;
static bt_cap_common_discover_func_t discover_cb_func;

struct bt_cap_common_proc *bt_cap_common_get_active_proc(void)
{
	return &active_proc;
}

void bt_cap_common_clear_active_proc(void)
{
	(void)memset(&active_proc, 0, sizeof(active_proc));
}

void bt_cap_common_start_proc(enum bt_cap_common_proc_type proc_type, size_t proc_cnt)
{
	atomic_set_bit(active_proc.proc_state_flags, BT_CAP_COMMON_PROC_STATE_ACTIVE);
	active_proc.proc_cnt = proc_cnt;
	active_proc.proc_type = proc_type;
	active_proc.proc_done_cnt = 0U;
	active_proc.proc_initiated_cnt = 0U;
}

#if defined(CONFIG_BT_CAP_INITIATOR_UNICAST)
void bt_cap_common_set_subproc(enum bt_cap_common_subproc_type subproc_type)
{
	active_proc.proc_done_cnt = 0U;
	active_proc.proc_initiated_cnt = 0U;
	active_proc.subproc_type = subproc_type;
}

bool bt_cap_common_subproc_is_type(enum bt_cap_common_subproc_type subproc_type)
{
	return active_proc.subproc_type == subproc_type;
}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */

struct bt_conn *bt_cap_common_get_member_conn(enum bt_cap_set_type type,
					      const union bt_cap_set_member *member)
{
	if (type == BT_CAP_SET_TYPE_CSIP) {
		struct bt_cap_common_client *client;

		/* We have verified that `client` won't be NULL in
		 * `valid_change_volume_param`.
		 */
		client = bt_cap_common_get_client_by_csis(member->csip);
		if (client != NULL) {
			return client->conn;
		}
	}

	return member->member;
}

bool bt_cap_common_proc_is_active(void)
{
	return atomic_test_bit(active_proc.proc_state_flags, BT_CAP_COMMON_PROC_STATE_ACTIVE);
}

bool bt_cap_common_proc_is_aborted(void)
{
	return atomic_test_bit(active_proc.proc_state_flags, BT_CAP_COMMON_PROC_STATE_ABORTED);
}

bool bt_cap_common_proc_all_handled(void)
{
	return active_proc.proc_done_cnt == active_proc.proc_initiated_cnt;
}

bool bt_cap_common_proc_is_done(void)
{
	return active_proc.proc_done_cnt == active_proc.proc_cnt;
}

void bt_cap_common_abort_proc(struct bt_conn *conn, int err)
{
	if (bt_cap_common_proc_is_aborted()) {
		/* no-op */
		return;
	}

	active_proc.err = err;
	active_proc.failed_conn = conn;
	atomic_set_bit(active_proc.proc_state_flags, BT_CAP_COMMON_PROC_STATE_ABORTED);
}

#if defined(CONFIG_BT_CAP_INITIATOR_UNICAST)
static bool active_proc_is_initiator(void)
{
	switch (active_proc.proc_type) {
	case BT_CAP_COMMON_PROC_TYPE_START:
	case BT_CAP_COMMON_PROC_TYPE_UPDATE:
	case BT_CAP_COMMON_PROC_TYPE_STOP:
		return true;
	default:
		return false;
	}
}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */

#if defined(CONFIG_BT_CAP_COMMANDER)
static bool active_proc_is_commander(void)
{
	switch (active_proc.proc_type) {
	case BT_CAP_COMMON_PROC_TYPE_VOLUME_CHANGE:
	case BT_CAP_COMMON_PROC_TYPE_VOLUME_OFFSET_CHANGE:
	case BT_CAP_COMMON_PROC_TYPE_VOLUME_MUTE_CHANGE:
	case BT_CAP_COMMON_PROC_TYPE_MICROPHONE_GAIN_CHANGE:
	case BT_CAP_COMMON_PROC_TYPE_MICROPHONE_MUTE_CHANGE:
		return true;
	default:
		return false;
	}
}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */

bool bt_cap_common_conn_in_active_proc(const struct bt_conn *conn)
{
	if (!bt_cap_common_proc_is_active()) {
		return false;
	}

	for (size_t i = 0U; i < active_proc.proc_initiated_cnt; i++) {
#if defined(CONFIG_BT_CAP_INITIATOR_UNICAST)
		if (active_proc_is_initiator()) {
			if (active_proc.proc_param.initiator[i].stream->bap_stream.conn == conn) {
				return true;
			}
		}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */
#if defined(CONFIG_BT_CAP_COMMANDER)
		if (active_proc_is_commander()) {
			if (active_proc.proc_param.commander[i].conn == conn) {
				return true;
			}
		}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */
	}

	return false;
}

bool bt_cap_common_stream_in_active_proc(const struct bt_cap_stream *cap_stream)
{
	if (!bt_cap_common_proc_is_active()) {
		return false;
	}

#if defined(CONFIG_BT_CAP_INITIATOR_UNICAST)
	if (active_proc_is_initiator()) {
		for (size_t i = 0U; i < active_proc.proc_cnt; i++) {
			if (active_proc.proc_param.initiator[i].stream == cap_stream) {
				return true;
			}
		}
	}
#endif /* CONFIG_BT_CAP_INITIATOR_UNICAST */

	return false;
}

void bt_cap_common_disconnected(struct bt_conn *conn, uint8_t reason)
{
	struct bt_cap_common_client *client = bt_cap_common_get_client_by_acl(conn);

	if (client->conn != NULL) {
		bt_conn_unref(client->conn);
	}
	(void)memset(client, 0, sizeof(*client));

	if (bt_cap_common_conn_in_active_proc(conn)) {
		bt_cap_common_abort_proc(conn, -ENOTCONN);
	}
}

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

struct bt_cap_common_client *bt_cap_common_get_client_by_acl(const struct bt_conn *acl)
{
	if (acl == NULL) {
		return NULL;
	}

	return &bt_cap_common_clients[bt_conn_index(acl)];
}

struct bt_cap_common_client *
bt_cap_common_get_client_by_csis(const struct bt_csip_set_coordinator_csis_inst *csis_inst)
{
	if (csis_inst == NULL) {
		return NULL;
	}

	for (size_t i = 0U; i < ARRAY_SIZE(bt_cap_common_clients); i++) {
		struct bt_cap_common_client *client = &bt_cap_common_clients[i];

		if (client->csis_inst == csis_inst) {
			return client;
		}
	}

	return NULL;
}

struct bt_cap_common_client *bt_cap_common_get_client(enum bt_cap_set_type type,
						      const union bt_cap_set_member *member)
{
	struct bt_cap_common_client *client = NULL;

	if (type == BT_CAP_SET_TYPE_AD_HOC) {
		CHECKIF(member->member == NULL) {
			LOG_DBG("member->member is NULL");
			return NULL;
		}

		client = bt_cap_common_get_client_by_acl(member->member);
	} else if (type == BT_CAP_SET_TYPE_CSIP) {
		CHECKIF(member->csip == NULL) {
			LOG_DBG("member->csip is NULL");
			return NULL;
		}

		client = bt_cap_common_get_client_by_csis(member->csip);
		if (client == NULL) {
			LOG_DBG("CSIS was not found for member");
			return NULL;
		}
	}

	if (client == NULL || !client->cas_found) {
		LOG_DBG("CAS was not found for member %p", member);
		return NULL;
	}

	return client;
}

static void cap_common_discover_complete(struct bt_conn *conn, int err,
					 const struct bt_csip_set_coordinator_csis_inst *csis_inst)
{
	if (discover_cb_func != NULL) {
		const bt_cap_common_discover_func_t cb_func = discover_cb_func;

		discover_cb_func = NULL;
		cb_func(conn, err, csis_inst);
	}
}

static void csis_client_discover_cb(struct bt_conn *conn,
				    const struct bt_csip_set_coordinator_set_member *member,
				    int err, size_t set_count)
{
	struct bt_cap_common_client *client;

	if (err != 0) {
		LOG_DBG("CSIS client discover failed: %d", err);

		cap_common_discover_complete(conn, err, NULL);

		return;
	}

	client = bt_cap_common_get_client_by_acl(conn);
	client->csis_inst =
		bt_csip_set_coordinator_csis_inst_by_handle(conn, client->csis_start_handle);

	if (member == NULL || set_count == 0 || client->csis_inst == NULL) {
		LOG_ERR("Unable to find CSIS for CAS");

		cap_common_discover_complete(conn, -ENODATA, NULL);
	} else {
		LOG_DBG("Found CAS with CSIS");
		cap_common_discover_complete(conn, 0, client->csis_inst);
	}
}

static uint8_t bt_cap_common_discover_included_cb(struct bt_conn *conn,
						  const struct bt_gatt_attr *attr,
						  struct bt_gatt_discover_params *params)
{
	if (attr == NULL) {
		LOG_DBG("CAS CSIS include not found");

		cap_common_discover_complete(conn, 0, NULL);
	} else {
		const struct bt_gatt_include *included_service = attr->user_data;
		struct bt_cap_common_client *client =
			CONTAINER_OF(params, struct bt_cap_common_client, param);

		/* If the remote CAS includes CSIS, we first check if we
		 * have already discovered it, and if so we can just retrieve it
		 * and forward it to the application. If not, then we start
		 * CSIS discovery
		 */
		client->csis_start_handle = included_service->start_handle;
		client->csis_inst = bt_csip_set_coordinator_csis_inst_by_handle(
			conn, client->csis_start_handle);
		if (client->csis_inst == NULL) {
			static struct bt_csip_set_coordinator_cb csis_client_cb = {
				.discover = csis_client_discover_cb,
			};
			static bool csis_cbs_registered;
			int err;

			LOG_DBG("CAS CSIS not known, discovering");

			if (!csis_cbs_registered) {
				bt_csip_set_coordinator_register_cb(&csis_client_cb);
				csis_cbs_registered = true;
			}

			err = bt_csip_set_coordinator_discover(conn);
			if (err != 0) {
				LOG_DBG("Discover failed (err %d)", err);
				cap_common_discover_complete(conn, err, NULL);
			}
		} else {
			LOG_DBG("Found CAS with CSIS");
			cap_common_discover_complete(conn, 0, client->csis_inst);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t bt_cap_common_discover_cas_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr,
					     struct bt_gatt_discover_params *params)
{
	if (attr == NULL) {
		cap_common_discover_complete(conn, -ENODATA, NULL);
	} else {
		const struct bt_gatt_service_val *prim_service = attr->user_data;
		struct bt_cap_common_client *client =
			CONTAINER_OF(params, struct bt_cap_common_client, param);
		int err;

		client->cas_found = true;
		client->conn = bt_conn_ref(conn);

		if (attr->handle == prim_service->end_handle) {
			LOG_DBG("Found CAS without CSIS");
			cap_common_discover_complete(conn, 0, NULL);

			return BT_GATT_ITER_STOP;
		}

		LOG_DBG("Found CAS, discovering included CSIS");

		params->uuid = NULL;
		params->start_handle = attr->handle + 1;
		params->end_handle = prim_service->end_handle;
		params->type = BT_GATT_DISCOVER_INCLUDE;
		params->func = bt_cap_common_discover_included_cb;

		err = bt_gatt_discover(conn, params);
		if (err != 0) {
			LOG_DBG("Discover failed (err %d)", err);

			cap_common_discover_complete(conn, err, NULL);
		}
	}

	return BT_GATT_ITER_STOP;
}

int bt_cap_common_discover(struct bt_conn *conn, bt_cap_common_discover_func_t func)
{
	struct bt_gatt_discover_params *param;
	int err;

	if (discover_cb_func != NULL) {
		return -EBUSY;
	}

	param = &bt_cap_common_clients[bt_conn_index(conn)].param;
	param->func = bt_cap_common_discover_cas_cb;
	param->uuid = cas_uuid;
	param->type = BT_GATT_DISCOVER_PRIMARY;
	param->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	param->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	discover_cb_func = func;

	err = bt_gatt_discover(conn, param);
	if (err != 0) {
		discover_cb_func = NULL;

		/* Report expected possible errors */
		if (err == -ENOTCONN || err == -ENOMEM) {
			return err;
		}

		LOG_DBG("Unexpected err %d from bt_gatt_discover", err);
		return -ENOEXEC;
	}

	return 0;
}
