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

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <sys/printk.h>
#include <sys/byteorder.h>
#include <zephyr.h>

#include <bluetooth/gatt.h>
#include <bluetooth/services/ots.h>
#include "ots_internal.h"
#include "ots_dir_list_internal.h"

#include <logging/log.h>

LOG_MODULE_DECLARE(bt_ots, CONFIG_BT_OTS_LOG_LEVEL);

#define OACP_PROC_TYPE_SIZE	1
#define OACP_RES_MAX_SIZE	3

static enum bt_gatt_ots_oacp_res_code oacp_read_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	struct bt_gatt_ots_oacp_read_params *params = &proc->read_params;

	LOG_DBG("Validating Read procedure with offset: 0x%08X and "
		"length: 0x%08X", params->offset, params->len);

	if (!ots->cur_obj) {
		return BT_GATT_OTS_OACP_RES_INV_OBJ;
	}

	if (!BT_OTS_OBJ_GET_PROP_READ(ots->cur_obj->metadata.props)) {
		return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
	}

	if (!bt_gatt_ots_l2cap_is_open(&ots->l2cap, conn)) {
		return BT_GATT_OTS_OACP_RES_CHAN_UNAVAIL;
	}

	if ((params->offset + (uint64_t) params->len) >
		ots->cur_obj->metadata.size.cur) {
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	}

	if (ots->cur_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
		return BT_GATT_OTS_OACP_RES_OBJ_LOCKED;
	}

	ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_READ_OP_STATE;
	ots->cur_obj->state.read_op.sent_len = 0;
	memcpy(&ots->cur_obj->state.read_op.oacp_params, &proc->read_params,
		sizeof(ots->cur_obj->state.read_op.oacp_params));

	LOG_DBG("Read procedure is accepted");

	return BT_GATT_OTS_OACP_RES_SUCCESS;
}

static enum bt_gatt_ots_oacp_res_code oacp_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	switch (proc->type) {
	case BT_GATT_OTS_OACP_PROC_READ:
		return oacp_read_proc_validate(conn, ots, proc);
	case BT_GATT_OTS_OACP_PROC_CREATE:
	case BT_GATT_OTS_OACP_PROC_DELETE:
	case BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC:
	case BT_GATT_OTS_OACP_PROC_EXECUTE:
	case BT_GATT_OTS_OACP_PROC_WRITE:
	case BT_GATT_OTS_OACP_PROC_ABORT:
	default:
		return BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
	}
};

static enum bt_gatt_ots_oacp_res_code oacp_command_decode(
	const uint8_t *buf, uint16_t len,
	struct bt_gatt_ots_oacp_proc *proc)
{
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *) buf, len);

	proc->type = net_buf_simple_pull_u8(&net_buf);
	switch (proc->type) {
	case BT_GATT_OTS_OACP_PROC_CREATE:
		proc->create_params.size = net_buf_simple_pull_le32(&net_buf);
		bt_uuid_create(&proc->create_params.type.uuid, net_buf.data,
			       net_buf.len);
		net_buf_simple_pull_mem(&net_buf, net_buf.len);
		break;
	case BT_GATT_OTS_OACP_PROC_DELETE:
		break;
	case BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC:
		proc->cs_calc_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->cs_calc_params.len =
			net_buf_simple_pull_le32(&net_buf);
		break;
	case BT_GATT_OTS_OACP_PROC_EXECUTE:
		break;
	case BT_GATT_OTS_OACP_PROC_READ:
		proc->read_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->read_params.len =
			net_buf_simple_pull_le32(&net_buf);
		return BT_GATT_OTS_OACP_RES_SUCCESS;
	case BT_GATT_OTS_OACP_PROC_WRITE:
		proc->write_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->write_params.len =
			net_buf_simple_pull_le32(&net_buf);
		proc->write_params.mode =
			net_buf_simple_pull_u8(&net_buf);
		break;
	case BT_GATT_OTS_OACP_PROC_ABORT:
	default:
		break;
	}

	LOG_WRN("OACP unsupported procedure type");
	return BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
}

static bool oacp_command_len_verify(struct bt_gatt_ots_oacp_proc *proc,
				    uint16_t len)
{
	uint16_t ref_len = OACP_PROC_TYPE_SIZE;

	switch (proc->type) {
	case BT_GATT_OTS_OACP_PROC_CREATE:
	{
		struct bt_ots_obj_type *type;

		ref_len += sizeof(proc->create_params.size);

		type = &proc->create_params.type;
		if (type->uuid.type == BT_UUID_TYPE_16) {
			ref_len += sizeof(type->uuid_16.val);
		} else if (type->uuid.type == BT_UUID_TYPE_128) {
			ref_len += sizeof(type->uuid_128.val);
		} else {
			return true;
		}
	} break;
	case BT_GATT_OTS_OACP_PROC_DELETE:
		break;
	case BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC:
		ref_len += sizeof(proc->cs_calc_params);
		break;
	case BT_GATT_OTS_OACP_PROC_EXECUTE:
		break;
	case BT_GATT_OTS_OACP_PROC_READ:
		ref_len += sizeof(proc->read_params);
		break;
	case BT_GATT_OTS_OACP_PROC_WRITE:
		ref_len += sizeof(proc->write_params);
		break;
	case BT_GATT_OTS_OACP_PROC_ABORT:
		break;
	default:
		return true;
	}

	return (len == ref_len);
}

static void oacp_read_proc_cb(struct bt_gatt_ots_l2cap *l2cap_ctx,
			      struct bt_conn *conn)
{
	int err;
	uint8_t *obj_chunk;
	uint32_t offset;
	uint32_t len;
	struct bt_ots *ots;
	struct bt_gatt_ots_object_read_op *read_op;

	ots     = CONTAINER_OF(l2cap_ctx, struct bt_ots, l2cap);
	read_op = &ots->cur_obj->state.read_op;
	offset  = read_op->oacp_params.offset + read_op->sent_len;

	if (read_op->sent_len >= read_op->oacp_params.len) {
		LOG_DBG("OACP Read Op over L2CAP is completed");

		if (read_op->sent_len > read_op->oacp_params.len) {
			LOG_WRN("More bytes sent that the client requested");
		}

		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;

		if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
		    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
			return;
		}

		ots->cb->obj_read(ots, conn, ots->cur_obj->id, NULL, 0,
				  offset);
		return;
	}

	len = read_op->oacp_params.len - read_op->sent_len;
	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
	    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
		len = bt_ots_dir_list_content_get(ots->dir_list, &obj_chunk, len, offset);
	} else {
		len = ots->cb->obj_read(ots, conn, ots->cur_obj->id, &obj_chunk,
					len, offset);
	}

	ots->l2cap.tx_done = oacp_read_proc_cb;
	err = bt_gatt_ots_l2cap_send(&ots->l2cap, obj_chunk, len);
	if (err) {
		LOG_ERR("L2CAP CoC error: %d while trying to execute OACP "
			"Read procedure", err);
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
	} else {
		read_op->sent_len += len;
	}
}

static void oacp_read_proc_execute(struct bt_ots *ots,
				   struct bt_conn *conn)
{
	struct bt_gatt_ots_oacp_read_params *params =
		&ots->cur_obj->state.read_op.oacp_params;

	if (!ots->cur_obj) {
		LOG_ERR("Invalid Current Object on OACP Read procedure");
		return;
	}

	LOG_DBG("Executing Read procedure with offset: 0x%08X and "
		"length: 0x%08X", params->offset, params->len);

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
	    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
		oacp_read_proc_cb(&ots->l2cap, conn);
	} else if (ots->cb->obj_read) {
		oacp_read_proc_cb(&ots->l2cap, conn);
	} else {
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
		LOG_ERR("OTS Read operation failed: "
			"there is no OTS Read callback");
	}
}

static void oacp_ind_cb(struct bt_conn *conn,
			struct bt_gatt_indicate_params *params,
			uint8_t err)
{
	struct bt_ots *ots = (struct bt_ots *) params->attr->user_data;

	LOG_DBG("Received OACP Indication ACK with status: 0x%04X", err);

	switch (ots->cur_obj->state.type) {
	case BT_GATT_OTS_OBJECT_READ_OP_STATE:
		oacp_read_proc_execute(ots, conn);
		break;
	default:
		LOG_ERR("Unsupported OTS state: %d", ots->cur_obj->state.type);
		break;
	}
}

static int oacp_ind_send(const struct bt_gatt_attr *oacp_attr,
			 enum bt_gatt_ots_oacp_proc_type req_op_code,
			 enum bt_gatt_ots_oacp_res_code oacp_status)
{
	uint8_t oacp_res[OACP_RES_MAX_SIZE];
	uint16_t oacp_res_len = 0;
	struct bt_ots *ots = (struct bt_ots *) oacp_attr->user_data;

	/* Encode OACP Response */
	oacp_res[oacp_res_len++] = BT_GATT_OTS_OACP_PROC_RESP;
	oacp_res[oacp_res_len++] = req_op_code;
	oacp_res[oacp_res_len++] = oacp_status;

	/* Prepare indication parameters */
	memset(&ots->oacp_ind.params, 0, sizeof(ots->oacp_ind.params));
	memcpy(&ots->oacp_ind.attr, oacp_attr, sizeof(ots->oacp_ind.attr));
	ots->oacp_ind.params.attr = &ots->oacp_ind.attr;
	ots->oacp_ind.params.func = oacp_ind_cb;
	ots->oacp_ind.params.data = oacp_res;
	ots->oacp_ind.params.len  = oacp_res_len;

	LOG_DBG("Sending OACP indication");

	return bt_gatt_indicate(NULL, &ots->oacp_ind.params);
}

ssize_t bt_gatt_ots_oacp_write(struct bt_conn *conn,
				   const struct bt_gatt_attr *attr,
				   const void *buf, uint16_t len,
				   uint16_t offset, uint8_t flags)
{
	enum bt_gatt_ots_oacp_res_code oacp_status;
	struct bt_gatt_ots_oacp_proc oacp_proc;
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("Object Action Control Point GATT Write Operation");

	if (!ots->oacp_ind.is_enabled) {
		LOG_WRN("OACP indications not enabled");
		return BT_GATT_ERR(BT_ATT_ERR_CCC_IMPROPER_CONF);
	}

	if (offset != 0) {
		LOG_ERR("Invalid offset of OACP Write Request");
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	oacp_status = oacp_command_decode(buf, len, &oacp_proc);

	if (!oacp_command_len_verify(&oacp_proc, len)) {
		LOG_ERR("Invalid length of OACP Write Request for 0x%02X "
			"Op Code", oacp_proc.type);
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	if (oacp_status == BT_GATT_OTS_OACP_RES_SUCCESS) {
		oacp_status = oacp_proc_validate(conn, ots, &oacp_proc);
	}

	if (oacp_status != BT_GATT_OTS_OACP_RES_SUCCESS) {
		LOG_WRN("OACP Write error status: 0x%02X", oacp_status);
	}

	oacp_ind_send(attr, oacp_proc.type, oacp_status);
	return len;
}

void bt_gatt_ots_oacp_cfg_changed(const struct bt_gatt_attr *attr,
				      uint16_t value)
{
	struct bt_gatt_ots_indicate *oacp_ind =
	    CONTAINER_OF((struct _bt_gatt_ccc *) attr->user_data,
			 struct bt_gatt_ots_indicate, ccc);

	LOG_DBG("Object Action Control Point CCCD value: 0x%04X", value);

	oacp_ind->is_enabled = false;
	if (value == BT_GATT_CCC_INDICATE) {
		oacp_ind->is_enabled = true;
	}
}
