/*
 * Copyright (c) 2022 Codecoup
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <stdint.h>
#include <zephyr/sys/check.h>
#include <zephyr/logging/log.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/services/ias.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_IAS_CLIENT)
#define LOG_MODULE_NAME bt_ias_client
#include "../../common/log.h"

enum {
	IAS_DISCOVER_IN_PROGRESS,

	IAS_NUM_FLAGS, /* keep as last */
};

struct bt_ias_client {
	/* Handle for alert writes */
	uint16_t alert_level_handle;

	/** Internal flags **/
	ATOMIC_DEFINE(flags, IAS_NUM_FLAGS);

	/* Gatt discover procedure parameters */
	struct bt_gatt_discover_params discover;
};

static const struct bt_uuid *alert_lvl_uuid = BT_UUID_ALERT_LEVEL;
static const struct bt_uuid *ias_uuid = BT_UUID_IAS;

static const struct bt_ias_client_cb *ias_client_cb;
static struct bt_ias_client client_list[CONFIG_BT_MAX_CONN];

static struct bt_ias_client *client_by_conn(struct bt_conn *conn)
{
	return &client_list[bt_conn_index(conn)];
}

static void client_cleanup(struct bt_ias_client *ias_client)
{
	(void)memset(ias_client, 0, sizeof(*ias_client));
}

static void discover_complete(struct bt_conn *conn, int err)
{
	BT_DBG("conn %p", (void *)conn);

	if (err) {
		client_cleanup(client_by_conn(conn));
		BT_DBG("Discover failed (err %d\n)", err);
	}

	if (ias_client_cb != NULL && ias_client_cb->discover != NULL) {
		ias_client_cb->discover(conn, err);
	}
}

int bt_ias_client_alert_write(struct bt_conn *conn, enum bt_ias_alert_lvl lvl)
{
	int err;
	uint8_t lvl_u8;

	CHECKIF(conn == NULL) {
		return -ENOTCONN;
	}

	if (client_by_conn(conn)->alert_level_handle == 0) {
		return -EINVAL;
	}

	lvl_u8 = (uint8_t)lvl;

	if (lvl_u8 < BT_IAS_ALERT_LVL_NO_ALERT || lvl_u8 > BT_IAS_ALERT_LVL_HIGH_ALERT) {
		BT_ERR("Invalid alert value: %u", lvl_u8);
		return -EINVAL;
	}

	err = bt_gatt_write_without_response(conn,
					     client_by_conn(conn)->alert_level_handle,
					     &lvl_u8, sizeof(lvl_u8), false);
	if (err < 0) {
		BT_ERR("IAS client level %d write failed: %d", lvl, err);
	}

	return err;
}

static uint8_t bt_ias_alert_lvl_disc_cb(struct bt_conn *conn,
					const struct bt_gatt_attr *attr,
					struct bt_gatt_discover_params *discover)
{
	const struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data;

	atomic_clear_bit(client_by_conn(conn)->flags, IAS_DISCOVER_IN_PROGRESS);

	if (attr == NULL) {
		discover_complete(conn, -ENOENT);

		return BT_GATT_ITER_STOP;
	}

	client_by_conn(conn)->alert_level_handle = chrc->value_handle;
	discover_complete(conn, 0);

	return BT_GATT_ITER_STOP;
}

static uint8_t bt_ias_prim_disc_cb(struct bt_conn *conn,
				   const struct bt_gatt_attr *attr,
				   struct bt_gatt_discover_params *discover)
{
	int err;
	const struct bt_gatt_service_val *data;
	struct bt_ias_client *client = client_by_conn(conn);

	if (!attr) {
		discover_complete(conn, -ENOENT);

		return BT_GATT_ITER_STOP;
	}

	data = attr->user_data;

	client->discover.uuid = alert_lvl_uuid;
	client->discover.start_handle = attr->handle + 1;
	client->discover.end_handle = data->end_handle;
	client->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	client->discover.func = bt_ias_alert_lvl_disc_cb;

	err = bt_gatt_discover(conn, &client->discover);
	if (err) {
		discover_complete(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

int bt_ias_discover(struct bt_conn *conn)
{
	int err;
	struct bt_ias_client *client = client_by_conn(conn);

	CHECKIF(!conn || !ias_client_cb || !ias_client_cb->discover) {
		return -EINVAL;
	}

	if (atomic_test_bit(client->flags, IAS_DISCOVER_IN_PROGRESS)) {
		return -EBUSY;
	}

	client_cleanup(client);
	atomic_set_bit(client->flags, IAS_DISCOVER_IN_PROGRESS);

	client->discover.uuid = ias_uuid;
	client->discover.func = bt_ias_prim_disc_cb;
	client->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	client->discover.type = BT_GATT_DISCOVER_PRIMARY;

	err = bt_gatt_discover(conn, &client->discover);
	if (err < 0) {
		discover_complete(conn, err);
	}

	return err;
}

int bt_ias_client_cb_register(const struct bt_ias_client_cb *cb)
{
	CHECKIF(!cb) {
		return -EINVAL;
	}

	CHECKIF(cb->discover == NULL) {
		return -EINVAL;
	}

	CHECKIF(ias_client_cb) {
		return -EALREADY;
	}

	ias_client_cb = cb;

	return 0;
}
