/*  Bluetooth VCP */

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

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.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/vcp.h>

#include "audio_internal.h"
#include "vcp_internal.h"

#define LOG_LEVEL CONFIG_BT_VCP_VOL_REND_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_vcp_vol_rend);

#define VOLUME_DOWN(current_vol) \
	((uint8_t)MAX(0, (int)current_vol - vol_rend.volume_step))
#define VOLUME_UP(current_vol) \
	((uint8_t)MIN(UINT8_MAX, (int)current_vol + vol_rend.volume_step))

#define VALID_VCP_OPCODE(opcode) ((opcode) <= BT_VCP_OPCODE_MUTE)

enum vol_rend_notify {
	NOTIFY_STATE,
	NOTIFY_FLAGS,
	NOTIFY_NUM,
};

struct bt_vcp_vol_rend {
	struct vcs_state state;
	uint8_t flags;
	struct bt_vcp_vol_rend_cb *cb;
	uint8_t volume_step;

	struct bt_gatt_service *service_p;
	struct bt_vocs *vocs_insts[CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT];
	struct bt_aics *aics_insts[CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT];

	ATOMIC_DEFINE(notify, NOTIFY_NUM);
	struct k_work_delayable notify_work;
};

static struct bt_vcp_vol_rend vol_rend;

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

static ssize_t read_vol_state(struct bt_conn *conn,
			      const struct bt_gatt_attr *attr, void *buf,
			      uint16_t len, uint16_t offset)
{
	LOG_DBG("Volume %u, mute %u, counter %u",
		vol_rend.state.volume, vol_rend.state.mute,
		vol_rend.state.change_counter);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &vol_rend.state, sizeof(vol_rend.state));
}

static const char *vol_rend_notify_str(enum vol_rend_notify notify)
{
	switch (notify) {
	case NOTIFY_STATE:
		return "state";
	case NOTIFY_FLAGS:
		return "flags";
	default:
		return "unknown";
	}
}

static void notify_work_reschedule(struct bt_vcp_vol_rend *inst, enum vol_rend_notify notify,
				   k_timeout_t delay)
{
	int err;

	atomic_set_bit(inst->notify, notify);

	err = k_work_reschedule(&inst->notify_work, delay);
	if (err < 0) {
		LOG_ERR("Failed to reschedule %s notification err %d", vol_rend_notify_str(notify),
			err);
	} else {
		LOG_DBG("%s notification scheduled in %dms", vol_rend_notify_str(notify),
			k_ticks_to_ms_floor32(k_work_delayable_remaining_get(&inst->notify_work)));
	}
}

static void notify(struct bt_vcp_vol_rend *inst, enum vol_rend_notify notify,
		   const struct bt_uuid *uuid, const void *data, uint16_t len)
{
	int err;

	err = bt_gatt_notify_uuid(NULL, uuid, inst->service_p->attrs, data, len);
	if (err == -ENOMEM) {
		notify_work_reschedule(inst, notify, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US));
	} else if (err < 0 && err != -ENOTCONN) {
		LOG_ERR("Notify %s err %d", vol_rend_notify_str(notify), err);
	}
}

static void notify_work_handler(struct k_work *work)
{
	struct k_work_delayable *d_work = k_work_delayable_from_work(work);
	struct bt_vcp_vol_rend *inst = CONTAINER_OF(d_work, struct bt_vcp_vol_rend, notify_work);

	if (atomic_test_and_clear_bit(inst->notify, NOTIFY_STATE)) {
		notify(inst, NOTIFY_STATE, BT_UUID_VCS_STATE, &inst->state, sizeof(inst->state));
	}

	if (IS_ENABLED(CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE) &&
	    atomic_test_and_clear_bit(inst->notify, NOTIFY_FLAGS)) {
		notify(inst, NOTIFY_FLAGS, BT_UUID_VCS_FLAGS, &inst->flags, sizeof(inst->flags));
	}
}

static void value_changed(struct bt_vcp_vol_rend *inst, enum vol_rend_notify notify)
{
	notify_work_reschedule(inst, notify, K_NO_WAIT);
}

static ssize_t write_vcs_control(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 const void *buf, uint16_t len, uint16_t offset,
				 uint8_t flags)
{
	const struct vcs_control_vol *cp_val = buf;
	bool notify = false;
	bool volume_change = false;
	uint8_t opcode;

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

	if (len == 0 || buf == NULL) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	/* Check opcode before length */
	if (!VALID_VCP_OPCODE(cp_val->cp.opcode)) {
		LOG_DBG("Invalid opcode %u", cp_val->cp.opcode);
		return BT_GATT_ERR(BT_VCP_ERR_OP_NOT_SUPPORTED);
	}

	if ((len < sizeof(struct vcs_control)) ||
	    (len == sizeof(struct vcs_control_vol) &&
	    cp_val->cp.opcode != BT_VCP_OPCODE_SET_ABS_VOL) ||
	    (len > sizeof(struct vcs_control_vol))) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	opcode = cp_val->cp.opcode;

	LOG_DBG("Opcode %u, counter %u", opcode, cp_val->cp.counter);

	if (cp_val->cp.counter != vol_rend.state.change_counter) {
		return BT_GATT_ERR(BT_VCP_ERR_INVALID_COUNTER);
	}

	switch (opcode) {
	case BT_VCP_OPCODE_REL_VOL_DOWN:
		LOG_DBG("Relative Volume Down (0x%x)", opcode);
		if (vol_rend.state.volume > 0) {
			vol_rend.state.volume = VOLUME_DOWN(vol_rend.state.volume);
			notify = true;
		}
		volume_change = true;
		break;
	case BT_VCP_OPCODE_REL_VOL_UP:
		LOG_DBG("Relative Volume Up (0x%x)", opcode);
		if (vol_rend.state.volume != UINT8_MAX) {
			vol_rend.state.volume = VOLUME_UP(vol_rend.state.volume);
			notify = true;
		}
		volume_change = true;
		break;
	case BT_VCP_OPCODE_UNMUTE_REL_VOL_DOWN:
		LOG_DBG("(Unmute) relative Volume Down (0x%x)", opcode);
		if (vol_rend.state.volume > 0) {
			vol_rend.state.volume = VOLUME_DOWN(vol_rend.state.volume);
			notify = true;
		}
		if (vol_rend.state.mute) {
			vol_rend.state.mute = BT_VCP_STATE_UNMUTED;
			notify = true;
		}
		volume_change = true;
		break;
	case BT_VCP_OPCODE_UNMUTE_REL_VOL_UP:
		LOG_DBG("(Unmute) relative Volume Up (0x%x)", opcode);
		if (vol_rend.state.volume != UINT8_MAX) {
			vol_rend.state.volume = VOLUME_UP(vol_rend.state.volume);
			notify = true;
		}
		if (vol_rend.state.mute) {
			vol_rend.state.mute = BT_VCP_STATE_UNMUTED;
			notify = true;
		}
		volume_change = true;
		break;
	case BT_VCP_OPCODE_SET_ABS_VOL:
		LOG_DBG("Set Absolute Volume (0x%x): Current volume %u",
			opcode, vol_rend.state.volume);
		if (vol_rend.state.volume != cp_val->volume) {
			vol_rend.state.volume = cp_val->volume;
			notify = true;
		}
		volume_change = true;
		break;
	case BT_VCP_OPCODE_UNMUTE:
		LOG_DBG("Unmute (0x%x)", opcode);
		if (vol_rend.state.mute) {
			vol_rend.state.mute = BT_VCP_STATE_UNMUTED;
			notify = true;
		}
		break;
	case BT_VCP_OPCODE_MUTE:
		LOG_DBG("Mute (0x%x)", opcode);
		if (vol_rend.state.mute == BT_VCP_STATE_UNMUTED) {
			vol_rend.state.mute = BT_VCP_STATE_MUTED;
			notify = true;
		}
		break;
	default:
		LOG_DBG("Unknown opcode (0x%x)", opcode);
		return BT_GATT_ERR(BT_VCP_ERR_OP_NOT_SUPPORTED);
	}

	if (notify) {
		vol_rend.state.change_counter++;
		LOG_DBG("New state: volume %u, mute %u, counter %u",
			vol_rend.state.volume, vol_rend.state.mute,
			vol_rend.state.change_counter);

		value_changed(&vol_rend, NOTIFY_STATE);

		if (vol_rend.cb && vol_rend.cb->state) {
			vol_rend.cb->state(0, vol_rend.state.volume,
					       vol_rend.state.mute);
		}
	}

	if (volume_change && !vol_rend.flags) {
		vol_rend.flags = 1;

		if (IS_ENABLED(CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE)) {
			value_changed(&vol_rend, NOTIFY_FLAGS);
		}

		if (vol_rend.cb && vol_rend.cb->flags) {
			vol_rend.cb->flags(0, vol_rend.flags);
		}
	}
	return len;
}

#if defined(CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE)
static void flags_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	LOG_DBG("value 0x%04x", value);
}
#endif /* CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE */

static ssize_t read_flags(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			  void *buf, uint16_t len, uint16_t offset)
{
	LOG_DBG("0x%02x", vol_rend.flags);
	return bt_gatt_attr_read(conn, attr, buf, len, offset, &vol_rend.flags,
				 sizeof(vol_rend.flags));
}

#define DUMMY_INCLUDE(i, _) BT_GATT_INCLUDE_SERVICE(NULL),
#define VOCS_INCLUDES(cnt) LISTIFY(cnt, DUMMY_INCLUDE, ())
#define AICS_INCLUDES(cnt) LISTIFY(cnt, DUMMY_INCLUDE, ())

/* Volume Control Service GATT Attributes */
static struct bt_gatt_attr vcs_attrs[] = {
	BT_GATT_PRIMARY_SERVICE(BT_UUID_VCS),
	VOCS_INCLUDES(CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT)
	AICS_INCLUDES(CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT)
	BT_AUDIO_CHRC(BT_UUID_VCS_STATE,
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
		      BT_GATT_PERM_READ_ENCRYPT,
		      read_vol_state, NULL, NULL),
	BT_AUDIO_CCC(volume_state_cfg_changed),
	BT_AUDIO_CHRC(BT_UUID_VCS_CONTROL,
		      BT_GATT_CHRC_WRITE,
		      BT_GATT_PERM_WRITE_ENCRYPT,
		      NULL, write_vcs_control, NULL),
#if defined(CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE)
	BT_AUDIO_CHRC(BT_UUID_VCS_FLAGS,
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
		      BT_GATT_PERM_READ_ENCRYPT,
		      read_flags, NULL, NULL),
	BT_AUDIO_CCC(flags_cfg_changed)
#else
	BT_AUDIO_CHRC(BT_UUID_VCS_FLAGS,
		      BT_GATT_CHRC_READ,
		      BT_GATT_PERM_READ_ENCRYPT,
		      read_flags, NULL, NULL)
#endif /* CONFIG_BT_VCP_VOL_REND_VOL_FLAGS_NOTIFIABLE */
};

static struct bt_gatt_service vcs_svc;

static int prepare_vocs_inst(struct bt_vcp_vol_rend_register_param *param)
{
	int err;
	int j;
	int i;

	if (CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT == 0) {
		return 0;
	}

	__ASSERT(param, "NULL param");

	for (j = 0, i = 0; i < ARRAY_SIZE(vcs_attrs); i++) {
		if (bt_uuid_cmp(vcs_attrs[i].uuid, BT_UUID_GATT_INCLUDE) == 0 &&
		    !vcs_attrs[i].user_data) {

			vol_rend.vocs_insts[j] = bt_vocs_free_instance_get();

			if (vol_rend.vocs_insts[j] == NULL) {
				LOG_ERR("Could not get free VOCS instances[%d]",
					j);
				return -ENOMEM;
			}

			err = bt_vocs_register(vol_rend.vocs_insts[j],
					       &param->vocs_param[j]);
			if (err != 0) {
				LOG_DBG("Could not register VOCS instance[%d]: %d",
					j, err);
				return err;
			}

			vcs_attrs[i].user_data = bt_vocs_svc_decl_get(vol_rend.vocs_insts[j]);
			j++;

			if (j == CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT) {
				break;
			}
		}
	}

	__ASSERT(j == CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT,
		 "Invalid VOCS instance count");

	return 0;
}

static int prepare_aics_inst(struct bt_vcp_vol_rend_register_param *param)
{
	int err;
	int j;
	int i;

	if (CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT == 0) {
		return 0;
	}

	__ASSERT(param, "NULL param");

	for (j = 0, i = 0; i < ARRAY_SIZE(vcs_attrs); i++) {
		if (bt_uuid_cmp(vcs_attrs[i].uuid, BT_UUID_GATT_INCLUDE) == 0 &&
		    !vcs_attrs[i].user_data) {
			vol_rend.aics_insts[j] = bt_aics_free_instance_get();

			if (vol_rend.aics_insts[j] == NULL) {
				LOG_ERR("Could not get free AICS instances[%d]",
					j);
				return -ENOMEM;
			}

			err = bt_aics_register(vol_rend.aics_insts[j],
					       &param->aics_param[j]);
			if (err != 0) {
				LOG_DBG("Could not register AICS instance[%d]: %d",
					j, err);
				return err;
			}

			vcs_attrs[i].user_data = bt_aics_svc_decl_get(vol_rend.aics_insts[j]);
			j++;

			LOG_DBG("AICS P %p", vcs_attrs[i].user_data);

			if (j == CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT) {
				break;
			}
		}
	}

	__ASSERT(j == CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT,
		 "Invalid AICS instance count");

	return 0;
}

/****************************** PUBLIC API ******************************/
int bt_vcp_vol_rend_register(struct bt_vcp_vol_rend_register_param *param)
{
	static bool registered;
	int err;

	CHECKIF(param == NULL) {
		LOG_DBG("param is NULL");
		return -EINVAL;
	}

	CHECKIF(param->mute > BT_VCP_STATE_MUTED) {
		LOG_DBG("Invalid mute value: %u", param->mute);
		return -EINVAL;
	}

	CHECKIF(param->step == 0) {
		LOG_DBG("Invalid step value: %u", param->step);
		return -EINVAL;
	}

	if (registered) {
		return -EALREADY;
	}

	vcs_svc = (struct bt_gatt_service)BT_GATT_SERVICE(vcs_attrs);

	if (CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT > 0) {
		err = prepare_vocs_inst(param);

		if (err != 0) {
			return err;
		}
	}

	if (CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT > 0) {
		err = prepare_aics_inst(param);

		if (err != 0) {
			return err;
		}
	}


	vol_rend.state.volume = param->volume;
	vol_rend.state.mute = param->mute;
	vol_rend.volume_step = param->step;
	vol_rend.service_p = &vcs_svc;

	err = bt_gatt_service_register(&vcs_svc);
	if (err != 0) {
		LOG_DBG("VCP service register failed: %d", err);
	}

	vol_rend.cb = param->cb;

	atomic_clear(vol_rend.notify);
	k_work_init_delayable(&vol_rend.notify_work, notify_work_handler);

	registered = true;

	return err;
}

int bt_vcp_vol_rend_included_get(struct bt_vcp_included *included)
{
	if (included == NULL) {
		return -EINVAL;
	}

	included->vocs_cnt = ARRAY_SIZE(vol_rend.vocs_insts);
	included->vocs = vol_rend.vocs_insts;

	included->aics_cnt = ARRAY_SIZE(vol_rend.aics_insts);
	included->aics = vol_rend.aics_insts;

	return 0;
}

int bt_vcp_vol_rend_set_step(uint8_t volume_step)
{
	if (volume_step > 0) {
		vol_rend.volume_step = volume_step;
		return 0;
	} else {
		return -EINVAL;
	}
}

int bt_vcp_vol_rend_get_state(void)
{
	if (vol_rend.cb && vol_rend.cb->state) {
		vol_rend.cb->state(0, vol_rend.state.volume,
				   vol_rend.state.mute);
	}

	return 0;
}

int bt_vcp_vol_rend_get_flags(void)
{
	if (vol_rend.cb && vol_rend.cb->flags) {
		vol_rend.cb->flags(0, vol_rend.flags);
	}

	return 0;
}

int bt_vcp_vol_rend_vol_down(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_REL_VOL_DOWN,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_vol_up(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_REL_VOL_UP,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_unmute_vol_down(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_UNMUTE_REL_VOL_DOWN,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_unmute_vol_up(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_UNMUTE_REL_VOL_UP,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_set_vol(uint8_t volume)
{
	const struct vcs_control_vol cp = {
		.cp = {
			.opcode = BT_VCP_OPCODE_SET_ABS_VOL,
			.counter = vol_rend.state.change_counter
		},
		.volume = volume
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_unmute(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_UNMUTE,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}

int bt_vcp_vol_rend_mute(void)
{
	const struct vcs_control cp = {
		.opcode = BT_VCP_OPCODE_MUTE,
		.counter = vol_rend.state.change_counter,
	};
	int err;

	err = write_vcs_control(NULL, NULL, &cp, sizeof(cp), 0, 0);

	return err > 0 ? 0 : err;
}
