/*
 * 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 <init.h>
#include <sys/printk.h>
#include <sys/byteorder.h>
#include <zephyr.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/conn.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt.h>

#include <sys/check.h>

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

#include <logging/log.h>

LOG_MODULE_REGISTER(bt_ots, CONFIG_BT_OTS_LOG_LEVEL);

#if defined(CONFIG_BT_OTS_OACP_READ_SUPPORT)
#define OACP_FEAT_BIT_READ BIT(BT_OTS_OACP_FEAT_READ)
#else
#define OACP_FEAT_BIT_READ 0
#endif

#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
#define OACP_FEAT_BIT_WRITE BIT(BT_OTS_OACP_FEAT_WRITE)
#else
#define OACP_FEAT_BIT_WRITE 0
#endif

#if defined(CONFIG_BT_OTS_OACP_PATCH_SUPPORT)
#define OACP_FEAT_BIT_PATCH BIT(BT_OTS_OACP_FEAT_PATCH)
#else
#define OACP_FEAT_BIT_PATCH 0
#endif

/* OACP features supported by Kconfig */
#define OACP_FEAT (		\
	OACP_FEAT_BIT_READ |	\
	OACP_FEAT_BIT_WRITE |	\
	OACP_FEAT_BIT_PATCH)

#if defined(CONFIG_BT_OTS_OLCP_GO_TO_SUPPORT)
#define OLCP_FEAT_BIT_GOTO BIT(BT_OTS_OLCP_FEAT_GO_TO)
#else
#define OLCP_FEAT_BIT_GOTO 0
#endif

/* OLCP features supported by Kconfig */
#define OLCP_FEAT OLCP_FEAT_BIT_GOTO

static bool ots_obj_validate_prop_against_oacp(uint32_t prop, uint32_t oacp)
{
	if (BT_OTS_OBJ_GET_PROP_DELETE(prop) > 0 && BT_OTS_OACP_GET_FEAT_DELETE(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_EXECUTE(prop) > 0 && BT_OTS_OACP_GET_FEAT_EXECUTE(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_READ(prop) > 0 && BT_OTS_OACP_GET_FEAT_READ(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_WRITE(prop) > 0 && BT_OTS_OACP_GET_FEAT_WRITE(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_APPEND(prop) > 0 && BT_OTS_OACP_GET_FEAT_APPEND(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_TRUNCATE(prop) > 0 && BT_OTS_OACP_GET_FEAT_TRUNCATE(oacp) == 0) {
		return false;
	}

	if (BT_OTS_OBJ_GET_PROP_PATCH(prop) > 0 && BT_OTS_OACP_GET_FEAT_PATCH(oacp) == 0) {
		return false;
	}

	return true;
}

static ssize_t ots_feature_read(struct bt_conn *conn,
				const struct bt_gatt_attr *attr, void *buf,
				uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("OTS Feature GATT Read Operation");

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &ots->features,
		sizeof(ots->features));
}

static ssize_t ots_obj_name_read(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr, void *buf,
				 uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("OTS Object Name GATT Read Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 ots->cur_obj->metadata.name,
				 strlen(ots->cur_obj->metadata.name));
}

#if defined(CONFIG_BT_OTS_OBJ_NAME_WRITE_SUPPORT)
ssize_t ots_obj_name_write(struct bt_conn *conn,
			   const struct bt_gatt_attr *attr,
			   const void *buf, uint16_t len,
			   uint16_t offset, uint8_t flags)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;
	struct bt_gatt_ots_object *obj = NULL;
	int rc = 0;
	char name[CONFIG_BT_OTS_OBJ_MAX_NAME_LEN + 1];

	LOG_DBG("OTS Object Name GATT Write Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
	    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
		LOG_DBG("Rejecting name write for the directory list object.");
		return BT_GATT_ERR(BT_GATT_OTS_WRITE_REQUEST_REJECTED);
	}

	if (offset > 0) {
		LOG_DBG("Rejecting a long write, offset must be 0!");
		return BT_GATT_ERR(BT_GATT_OTS_WRITE_REQUEST_REJECTED);
	}

	if (len > CONFIG_BT_OTS_OBJ_MAX_NAME_LEN) {
		LOG_DBG("Object name is too long!");
		return BT_GATT_ERR(BT_GATT_OTS_WRITE_REQUEST_REJECTED);
	}

	/* Construct a temporary name for duplication detection */
	memcpy(name, buf, len);
	name[len] = '\0';

	rc = bt_gatt_ots_obj_manager_first_obj_get(ots->obj_manager, &obj);
	while (rc == 0) {
		if (obj != ots->cur_obj && strcmp(name, obj->metadata.name) == 0) {
			LOG_DBG("Object name is duplicated!");
			return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NAME_ALREADY_EXISTS);
		}
		rc = bt_gatt_ots_obj_manager_next_obj_get(ots->obj_manager, obj, &obj);
	}

	/* Update real object name after no duplicate detected */
	strcpy(ots->cur_obj->metadata.name, name);

	if (ots->cb->obj_name_written) {
		ots->cb->obj_name_written(ots, conn, ots->cur_obj->id,
					  ots->cur_obj->metadata.name);
	}

	return len;
}
#endif

static ssize_t ots_obj_type_read(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr, void *buf,
				 uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;
	struct bt_ots_obj_metadata *obj_meta;

	LOG_DBG("OTS Object Type GATT Read Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	obj_meta = &ots->cur_obj->metadata;
	if (obj_meta->type.uuid.type == BT_UUID_TYPE_128) {
		return bt_gatt_attr_read(conn, attr, buf, len, offset,
					 obj_meta->type.uuid_128.val,
					 sizeof(obj_meta->type.uuid_128.val));
	} else {
		return bt_gatt_attr_read(conn, attr, buf, len, offset,
					 &obj_meta->type.uuid_16.val,
					 sizeof(obj_meta->type.uuid_16.val));
	}
}

static ssize_t ots_obj_size_read(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr, void *buf,
				 uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("OTS Object Size GATT Read Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &ots->cur_obj->metadata.size,
				 sizeof(ots->cur_obj->metadata.size));
}

static ssize_t ots_obj_id_read(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr, void *buf,
			       uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;
	uint8_t id[BT_OTS_OBJ_ID_SIZE];
	char id_str[BT_OTS_OBJ_ID_STR_LEN];

	LOG_DBG("OTS Object ID GATT Read Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	sys_put_le48(ots->cur_obj->id, id);

	bt_ots_obj_id_to_str(ots->cur_obj->id, id_str,
				      sizeof(id_str));
	LOG_DBG("Current Object ID: %s", log_strdup(id_str));

	return bt_gatt_attr_read(conn, attr, buf, len, offset, id, sizeof(id));
}

static ssize_t ots_obj_prop_read(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr, void *buf,
				 uint16_t len, uint16_t offset)
{
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("OTS Object Properties GATT Read Operation");

	if (!ots->cur_obj) {
		LOG_DBG("No Current Object selected in OTS!");
		return BT_GATT_ERR(BT_GATT_OTS_OBJECT_NOT_SELECTED);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &ots->cur_obj->metadata.props,
				 sizeof(ots->cur_obj->metadata.props));
}

int bt_ots_obj_add(struct bt_ots *ots,
			    struct bt_ots_obj_metadata *obj_init)
{
	int err;
	struct bt_gatt_ots_object *obj;
	size_t name_len;

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) && ots->dir_list &&
	    ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
		LOG_DBG("Directory Listing Object is being read");
		return -EBUSY;
	}

	name_len = strlen(obj_init->name);

	CHECKIF(name_len == 0 || name_len > CONFIG_BT_OTS_OBJ_MAX_NAME_LEN) {
		LOG_DBG("Invalid name length %zu", name_len);
		return -EINVAL;
	}

	CHECKIF(!ots_obj_validate_prop_against_oacp(obj_init->props, ots->features.oacp)) {
		LOG_DBG("Object properties (0x%04X) are not a subset of OACP (0x%04X)",
				obj_init->props, ots->features.oacp);
		return -ENOTSUP;
	}

	err = bt_gatt_ots_obj_manager_obj_add(ots->obj_manager, &obj);
	if (err) {
		LOG_ERR("No space available in the object manager");
		return err;
	}

	/* Initialize object. */
	memcpy(&obj->metadata, obj_init, sizeof(obj->metadata));

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
		bt_ots_dir_list_obj_add(ots->dir_list, ots->obj_manager, ots->cur_obj, obj);
	}

	/* Request object data. */
	if (ots->cb->obj_created) {
		err = ots->cb->obj_created(ots, NULL, obj->id, obj_init);
		if (err) {
			bt_gatt_ots_obj_manager_obj_delete(obj);

			if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
				bt_ots_dir_list_obj_remove(ots->dir_list, ots->obj_manager,
							   ots->cur_obj, obj);
			}

			return err;
		}
	}

	return 0;
}

int bt_ots_obj_delete(struct bt_ots *ots, uint64_t id)
{
	int err;
	struct bt_gatt_ots_object *obj;

	err = bt_gatt_ots_obj_manager_obj_get(ots->obj_manager, id, &obj);
	if (err) {
		return err;
	}

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

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) && ots->dir_list &&
	    ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
		LOG_DBG("Directory Listing Object is being read");
		return -EBUSY;
	}

	err = bt_gatt_ots_obj_manager_obj_delete(obj);
	if (err) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
		bt_ots_dir_list_obj_remove(ots->dir_list, ots->obj_manager, ots->cur_obj, obj);
	}

	if (ots->cb->obj_deleted) {
		ots->cb->obj_deleted(ots, NULL, obj->id);
	}

	return 0;
}

#if defined(CONFIG_BT_OTS_SECONDARY_SVC)
void *bt_ots_svc_decl_get(struct bt_ots *ots)
{
	return ots->service->attrs;
}
#endif

int bt_ots_init(struct bt_ots *ots,
		     struct bt_ots_init *ots_init)
{
	int err;

	if (!ots || !ots_init || !ots_init->cb) {
		return -EINVAL;
	}

	__ASSERT(ots_init->cb->obj_created,
		 "Callback for object creation is not set");
	__ASSERT(ots_init->cb->obj_read ||
		 !BT_OTS_OACP_GET_FEAT_READ(ots_init->features.oacp),
		 "Callback for object reading is not set");
	__ASSERT(ots_init->cb->obj_write ||
		 !BT_OTS_OACP_GET_FEAT_WRITE(ots_init->features.oacp),
		 "Callback for object write is not set");

	/* Set callback structure. */
	ots->cb = ots_init->cb;

	/* Check OACP supported features against Kconfig. */
	if (ots_init->features.oacp & (~((uint32_t) OACP_FEAT))) {
		return -ENOTSUP;
	}

	ots->features.oacp = ots_init->features.oacp;
	LOG_DBG("OACP features: 0x%04X", ots->features.oacp);

	/* Check OLCP supported features against Kconfig. */
	if (ots_init->features.olcp & (~((uint32_t) OLCP_FEAT))) {
		return -ENOTSUP;
	}
	ots->features.olcp = ots_init->features.olcp;
	LOG_DBG("OLCP features: 0x%04X", ots->features.olcp);

	/* Register L2CAP context. */
	err = bt_gatt_ots_l2cap_register(&ots->l2cap);
	if (err) {
		return err;
	}

	err = bt_gatt_service_register(ots->service);
	if (err) {
		bt_gatt_ots_l2cap_unregister(&ots->l2cap);

		return err;
	}

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
		bt_ots_dir_list_init(&ots->dir_list, ots->obj_manager);
	}

	LOG_DBG("Initialized OTS");

	return 0;
}

#if defined(CONFIG_BT_OTS_SECONDARY_SVC)
	#define BT_GATT_OTS_SERVICE	BT_GATT_SECONDARY_SERVICE
#else
	#define BT_GATT_OTS_SERVICE	BT_GATT_PRIMARY_SERVICE
#endif

#if defined(CONFIG_BT_OTS_OBJ_NAME_WRITE_SUPPORT)
	#define BT_OTS_OBJ_NAME_GATT_CHRC  (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE)
	#define BT_OTS_OBJ_NAME_GATT_PERM  (BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
	#define BT_OTS_OBJ_NAME_GATT_WRITE (ots_obj_name_write)
#else
	#define BT_OTS_OBJ_NAME_GATT_CHRC  (BT_GATT_CHRC_READ)
	#define BT_OTS_OBJ_NAME_GATT_PERM  (BT_GATT_PERM_READ)
	#define BT_OTS_OBJ_NAME_GATT_WRITE (NULL)
#endif

#define BT_GATT_OTS_ATTRS(_ots) {					\
	BT_GATT_OTS_SERVICE(BT_UUID_OTS),				\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_FEATURE,			\
		BT_GATT_CHRC_READ, BT_GATT_PERM_READ,			\
		ots_feature_read, NULL, &_ots),				\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_NAME,			\
		BT_OTS_OBJ_NAME_GATT_CHRC, BT_OTS_OBJ_NAME_GATT_PERM,	\
		ots_obj_name_read, BT_OTS_OBJ_NAME_GATT_WRITE, &_ots),	\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_TYPE,			\
		BT_GATT_CHRC_READ, BT_GATT_PERM_READ,			\
		ots_obj_type_read, NULL, &_ots),			\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_SIZE,			\
		BT_GATT_CHRC_READ, BT_GATT_PERM_READ,			\
		ots_obj_size_read, NULL, &_ots),			\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_ID,				\
		BT_GATT_CHRC_READ, BT_GATT_PERM_READ,			\
		ots_obj_id_read, NULL, &_ots),				\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_PROPERTIES,			\
		BT_GATT_CHRC_READ, BT_GATT_PERM_READ,			\
		ots_obj_prop_read, NULL, &_ots),			\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_ACTION_CP,			\
		BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE,		\
		BT_GATT_PERM_WRITE, NULL,				\
		bt_gatt_ots_oacp_write, &_ots),				\
	BT_GATT_CCC_MANAGED(&_ots.oacp_ind.ccc,				\
		BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),		\
	BT_GATT_CHARACTERISTIC(BT_UUID_OTS_LIST_CP,			\
		BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE,		\
		BT_GATT_PERM_WRITE, NULL,				\
		bt_gatt_ots_olcp_write, &_ots),				\
	BT_GATT_CCC_MANAGED(&_ots.olcp_ind.ccc,				\
		BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)			\
}

#define BT_GATT_OTS_INSTANCE_LIST_SIZE	(ARRAY_SIZE(ots_instances))
#define BT_GATT_OTS_INSTANCE_LIST_START	ots_instances
#define BT_GATT_OTS_INSTANCE_LIST_END	\
	(&ots_instances[BT_GATT_OTS_INSTANCE_LIST_SIZE])

#define BT_GATT_OTS_SERVICE_LIST_START	ots_service_list

static struct bt_ots ots_instances[CONFIG_BT_OTS_MAX_INST_CNT];
static uint32_t instance_cnt;
BT_GATT_SERVICE_INSTANCE_DEFINE(ots_service_list, ots_instances,
				CONFIG_BT_OTS_MAX_INST_CNT,
				BT_GATT_OTS_ATTRS);

struct bt_ots *bt_ots_free_instance_get(void)
{
	if (instance_cnt >= BT_GATT_OTS_INSTANCE_LIST_SIZE) {
		return NULL;
	}

	return &BT_GATT_OTS_INSTANCE_LIST_START[instance_cnt++];
}

static int bt_gatt_ots_instances_prepare(const struct device *dev)
{
	uint32_t index;
	struct bt_ots *instance;

	for (instance = BT_GATT_OTS_INSTANCE_LIST_START, index = 0;
	     instance != BT_GATT_OTS_INSTANCE_LIST_END;
	     instance++, index++) {
		/* Assign an object pool to the OTS instance. */
		instance->obj_manager = bt_gatt_ots_obj_manager_assign();

		if (!instance->obj_manager) {
			LOG_ERR("OTS Object manager instance not available");
			return -ENOMEM;
		}

		/* Assign pointer to the service descriptor. */
		instance->service = &BT_GATT_OTS_SERVICE_LIST_START[index];

		/* Initialize CCC descriptors for characteristics with
		 * indication properties.
		 */
		instance->oacp_ind.ccc.cfg_changed =
			bt_gatt_ots_oacp_cfg_changed;
		instance->olcp_ind.ccc.cfg_changed =
			bt_gatt_ots_olcp_cfg_changed;
	}

	return 0;
}

SYS_INIT(bt_gatt_ots_instances_prepare, APPLICATION,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
