/*
 * 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:
		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;
}
