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

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

#include <logging/log.h>

LOG_MODULE_DECLARE(bt_ots, CONFIG_BT_OTS_LOG_LEVEL);

/**Start of the usable range of Object IDs (values 0 to 0x100 are reserved)*/
#define OTS_OBJ_ID_START_RANGE  0x000000000100

#define OTS_OBJ_INDEX_TO_ID(_index) (OTS_OBJ_ID_START_RANGE + (_index))
#define OTS_OBJ_ID_TO_INDEX(_id)    ((_id) - OTS_OBJ_ID_START_RANGE)

struct bt_gatt_ots_pool_item {
	sys_dnode_t dnode;
	struct bt_gatt_ots_object val;
	bool is_allocated;
};

struct bt_gatt_ots_obj_manager {
	sys_dlist_t list;
	struct bt_gatt_ots_pool_item pool[CONFIG_BT_OTS_MAX_OBJ_CNT];
	bool is_assigned;
};

int bt_gatt_ots_obj_manager_first_obj_get(
	struct bt_gatt_ots_obj_manager *obj_manager,
	struct bt_gatt_ots_object **obj)
{
	sys_dnode_t *obj_dnode;
	struct bt_gatt_ots_pool_item *first_item;

	if (sys_dlist_is_empty(&obj_manager->list)) {
		return -ENOENT;
	}

	obj_dnode = sys_dlist_peek_head_not_empty(&obj_manager->list);
	first_item = CONTAINER_OF(obj_dnode, struct bt_gatt_ots_pool_item,
				  dnode);
	*obj = &first_item->val;

	return 0;
}

int bt_gatt_ots_obj_manager_last_obj_get(
	struct bt_gatt_ots_obj_manager *obj_manager,
	struct bt_gatt_ots_object **obj)
{
	sys_dnode_t *obj_dnode;
	struct bt_gatt_ots_pool_item *last_item;

	if (sys_dlist_is_empty(&obj_manager->list)) {
		return -ENOENT;
	}

	obj_dnode = sys_dlist_peek_tail(&obj_manager->list);
	last_item = CONTAINER_OF(obj_dnode, struct bt_gatt_ots_pool_item,
				 dnode);
	*obj = &last_item->val;

	return 0;
}

int bt_gatt_ots_obj_manager_prev_obj_get(
	struct bt_gatt_ots_obj_manager *obj_manager,
	const struct bt_gatt_ots_object *cur_obj,
	struct bt_gatt_ots_object **prev_obj)
{
	sys_dnode_t *prev_obj_dnode;
	struct bt_gatt_ots_pool_item *cur_item, *prev_item;

	if (sys_dlist_is_empty(&obj_manager->list)) {
		return -ENOENT;
	}

	cur_item = CONTAINER_OF(cur_obj, struct bt_gatt_ots_pool_item, val);
	prev_obj_dnode = sys_dlist_peek_prev_no_check(&obj_manager->list,
						      &cur_item->dnode);
	if (!prev_obj_dnode) {
		return -ENFILE;
	}

	prev_item = CONTAINER_OF(prev_obj_dnode,
				 struct bt_gatt_ots_pool_item,
				 dnode);
	*prev_obj = &prev_item->val;

	return 0;
}

int bt_gatt_ots_obj_manager_next_obj_get(
	struct bt_gatt_ots_obj_manager *obj_manager,
	const struct bt_gatt_ots_object *cur_obj,
	struct bt_gatt_ots_object **next_obj)
{
	sys_dnode_t *next_obj_dnode;
	struct bt_gatt_ots_pool_item *cur_item, *next_item;

	if (sys_dlist_is_empty(&obj_manager->list)) {
		return -ENOENT;
	}

	cur_item = CONTAINER_OF(cur_obj, struct bt_gatt_ots_pool_item, val);
	next_obj_dnode = sys_dlist_peek_next_no_check(&obj_manager->list,
						      &cur_item->dnode);
	if (!next_obj_dnode) {
		return -ENFILE;
	}

	next_item = CONTAINER_OF(next_obj_dnode,
				 struct bt_gatt_ots_pool_item,
				 dnode);
	*next_obj = &next_item->val;

	return 0;
}

int bt_gatt_ots_obj_manager_obj_get(
	struct bt_gatt_ots_obj_manager *obj_manager, uint64_t id,
	struct bt_gatt_ots_object **object)
{
	uint64_t i = OTS_OBJ_ID_TO_INDEX(id);

	if (sys_dlist_is_empty(&obj_manager->list)) {
		return -ENOENT;
	}

	if (id < OTS_OBJ_ID_START_RANGE) {
		return -EINVAL;
	}

	if (i >= ARRAY_SIZE(obj_manager->pool)) {
		return -EINVAL;
	}

	if (!obj_manager->pool[i].is_allocated) {
		return -EINVAL;
	}

	*object = &obj_manager->pool[i].val;

	return 0;
}

int bt_gatt_ots_obj_manager_obj_add(
	struct bt_gatt_ots_obj_manager *obj_manager,
	struct bt_gatt_ots_object **object)
{
	for (uint64_t i = 0; i < ARRAY_SIZE(obj_manager->pool); i++) {
		struct bt_gatt_ots_pool_item *cur_obj =
			&obj_manager->pool[i];

		if (!cur_obj->is_allocated) {
			cur_obj->is_allocated = true;
			cur_obj->val.id = OTS_OBJ_INDEX_TO_ID(i);
			sys_dlist_append(&obj_manager->list, &cur_obj->dnode);

			*object = &cur_obj->val;
			return 0;
		}
	}

	return -ENOMEM;
}

int bt_gatt_ots_obj_manager_obj_delete(struct bt_gatt_ots_object *obj)
{
	struct bt_gatt_ots_pool_item *item;

	item = CONTAINER_OF(obj, struct bt_gatt_ots_pool_item, val);

	if (!item->is_allocated) {
		return -EINVAL;
	}

	item->is_allocated = false;
	sys_dlist_remove(&item->dnode);

	return 0;
}

void *bt_gatt_ots_obj_manager_assign(void)
{
	static struct bt_gatt_ots_obj_manager
		obj_manager[CONFIG_BT_OTS_MAX_INST_CNT];
	struct bt_gatt_ots_obj_manager *cur_manager;


	for (cur_manager = obj_manager;
	     cur_manager != obj_manager + CONFIG_BT_OTS_MAX_INST_CNT;
	     cur_manager++) {
		if (!cur_manager->is_assigned) {
			break;
		}
	}

	if (cur_manager->is_assigned) {
		return NULL;
	}

	cur_manager->is_assigned = true;
	sys_dlist_init(&cur_manager->list);

	return cur_manager;
}
