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

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

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>

#include <zephyr/bluetooth/services/ots.h>

#define DEVICE_NAME      CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN  (sizeof(DEVICE_NAME) - 1)

#define OBJ_POOL_SIZE CONFIG_BT_OTS_MAX_OBJ_CNT
#define OBJ_MAX_SIZE  100

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};

static const struct bt_data sd[] = {
	BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_OTS_VAL)),
};

static struct {
	uint8_t data[OBJ_MAX_SIZE];
	char name[CONFIG_BT_OTS_OBJ_MAX_NAME_LEN + 1];
} objects[OBJ_POOL_SIZE];
static uint32_t obj_cnt;

struct object_creation_data {
	struct bt_ots_obj_size size;
	char *name;
	uint32_t props;
};

static struct object_creation_data *object_being_created;

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err) {
		printk("Connection failed (err %u)\n", err);
		return;
	}

	printk("Connected\n");
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected (reason %u)\n", reason);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
};

static int ots_obj_created(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
			   const struct bt_ots_obj_add_param *add_param,
			   struct bt_ots_obj_created_desc *created_desc)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];
	uint64_t index;

	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	if (obj_cnt >= ARRAY_SIZE(objects)) {
		printk("No item from Object pool is available for Object "
		       "with %s ID\n", id_str);
		return -ENOMEM;
	}

	if (add_param->size > OBJ_MAX_SIZE) {
		printk("Object pool item is too small for Object with %s ID\n",
		       id_str);
		return -ENOMEM;
	}

	if (object_being_created) {
		created_desc->name = object_being_created->name;
		created_desc->size = object_being_created->size;
		created_desc->props = object_being_created->props;
	} else {
		index = id - BT_OTS_OBJ_ID_MIN;
		objects[index].name[0] = '\0';

		created_desc->name = objects[index].name;
		created_desc->size.alloc = OBJ_MAX_SIZE;
		BT_OTS_OBJ_SET_PROP_READ(created_desc->props);
		BT_OTS_OBJ_SET_PROP_WRITE(created_desc->props);
		BT_OTS_OBJ_SET_PROP_PATCH(created_desc->props);
		BT_OTS_OBJ_SET_PROP_DELETE(created_desc->props);
	}

	printk("Object with %s ID has been created\n", id_str);
	obj_cnt++;

	return 0;
}

static int ots_obj_deleted(struct bt_ots *ots, struct bt_conn *conn,
			    uint64_t id)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];

	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	printk("Object with %s ID has been deleted\n", id_str);

	obj_cnt--;

	return 0;
}

static void ots_obj_selected(struct bt_ots *ots, struct bt_conn *conn,
			     uint64_t id)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];

	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	printk("Object with %s ID has been selected\n", id_str);
}

static ssize_t ots_obj_read(struct bt_ots *ots, struct bt_conn *conn,
			   uint64_t id, void **data, size_t len,
			   off_t offset)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];
	uint32_t obj_index = ((id - BT_OTS_OBJ_ID_MIN) % ARRAY_SIZE(objects));
	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	if (!data) {
		printk("Object with %s ID has been successfully read\n",
		       id_str);

		return 0;
	}

	*data = &objects[obj_index].data[offset];

	/* Send even-indexed objects in 20 byte packets
	 * to demonstrate fragmented transmission.
	 */
	if ((obj_index % 2) == 0) {
		len = (len < 20) ? len : 20;
	}

	printk("Object with %s ID is being read\n"
		"Offset = %lu, Length = %zu\n",
		id_str, (long)offset, len);

	return len;
}

static ssize_t ots_obj_write(struct bt_ots *ots, struct bt_conn *conn,
			     uint64_t id, const void *data, size_t len,
			     off_t offset, size_t rem)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];
	uint32_t obj_index = ((id - BT_OTS_OBJ_ID_MIN) % ARRAY_SIZE(objects));

	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	printk("Object with %s ID is being written\n"
		"Offset = %lu, Length = %zu, Remaining= %zu\n",
		id_str, (long)offset, len, rem);

	(void)memcpy(&objects[obj_index].data[offset], data, len);

	return len;
}

static void ots_obj_name_written(struct bt_ots *ots, struct bt_conn *conn,
				 uint64_t id, const char *cur_name, const char *new_name)
{
	char id_str[BT_OTS_OBJ_ID_STR_LEN];

	bt_ots_obj_id_to_str(id, id_str, sizeof(id_str));

	printk("Name for object with %s ID is being changed from '%s' to '%s'\n",
		id_str, cur_name, new_name);
}

static struct bt_ots_cb ots_callbacks = {
	.obj_created = ots_obj_created,
	.obj_deleted = ots_obj_deleted,
	.obj_selected = ots_obj_selected,
	.obj_read = ots_obj_read,
	.obj_write = ots_obj_write,
	.obj_name_written = ots_obj_name_written,
};

static int ots_init(void)
{
	int err;
	struct bt_ots *ots;
	struct object_creation_data obj_data;
	struct bt_ots_init ots_init;
	struct bt_ots_obj_add_param param;
	const char * const first_object_name = "first_object.txt";
	const char * const second_object_name = "second_object.gif";
	uint32_t cur_size;
	uint32_t alloc_size;

	ots = bt_ots_free_instance_get();
	if (!ots) {
		printk("Failed to retrieve OTS instance\n");
		return -ENOMEM;
	}

	/* Configure OTS initialization. */
	(void)memset(&ots_init, 0, sizeof(ots_init));
	BT_OTS_OACP_SET_FEAT_READ(ots_init.features.oacp);
	BT_OTS_OACP_SET_FEAT_WRITE(ots_init.features.oacp);
	BT_OTS_OACP_SET_FEAT_CREATE(ots_init.features.oacp);
	BT_OTS_OACP_SET_FEAT_DELETE(ots_init.features.oacp);
	BT_OTS_OACP_SET_FEAT_PATCH(ots_init.features.oacp);
	BT_OTS_OLCP_SET_FEAT_GO_TO(ots_init.features.olcp);
	ots_init.cb = &ots_callbacks;

	/* Initialize OTS instance. */
	err = bt_ots_init(ots, &ots_init);
	if (err) {
		printk("Failed to init OTS (err:%d)\n", err);
		return err;
	}

	/* Prepare first object demo data and add it to the instance. */
	cur_size = sizeof(objects[0].data) / 2;
	alloc_size = sizeof(objects[0].data);
	for (uint32_t i = 0; i < cur_size; i++) {
		objects[0].data[i] = i + 1;
	}

	(void)memset(&obj_data, 0, sizeof(obj_data));
	__ASSERT(strlen(first_object_name) <= CONFIG_BT_OTS_OBJ_MAX_NAME_LEN,
		 "Object name length is larger than the allowed maximum of %u",
		 CONFIG_BT_OTS_OBJ_MAX_NAME_LEN);
	(void)strcpy(objects[0].name, first_object_name);
	obj_data.name = objects[0].name;
	obj_data.size.cur = cur_size;
	obj_data.size.alloc = alloc_size;
	BT_OTS_OBJ_SET_PROP_READ(obj_data.props);
	BT_OTS_OBJ_SET_PROP_WRITE(obj_data.props);
	BT_OTS_OBJ_SET_PROP_PATCH(obj_data.props);
	object_being_created = &obj_data;

	param.size = alloc_size;
	param.type.uuid.type = BT_UUID_TYPE_16;
	param.type.uuid_16.val = BT_UUID_OTS_TYPE_UNSPECIFIED_VAL;
	err = bt_ots_obj_add(ots, &param);
	object_being_created = NULL;
	if (err < 0) {
		printk("Failed to add an object to OTS (err: %d)\n", err);
		return err;
	}

	/* Prepare second object demo data and add it to the instance. */
	cur_size = sizeof(objects[0].data);
	alloc_size = sizeof(objects[0].data);
	for (uint32_t i = 0; i < cur_size; i++) {
		objects[1].data[i] = i * 2;
	}

	(void)memset(&obj_data, 0, sizeof(obj_data));
	__ASSERT(strlen(second_object_name) <= CONFIG_BT_OTS_OBJ_MAX_NAME_LEN,
		 "Object name length is larger than the allowed maximum of %u",
		 CONFIG_BT_OTS_OBJ_MAX_NAME_LEN);
	(void)strcpy(objects[1].name, second_object_name);
	obj_data.name = objects[1].name;
	obj_data.size.cur = cur_size;
	obj_data.size.alloc = alloc_size;
	BT_OTS_OBJ_SET_PROP_READ(obj_data.props);
	object_being_created = &obj_data;

	param.size = alloc_size;
	param.type.uuid.type = BT_UUID_TYPE_16;
	param.type.uuid_16.val = BT_UUID_OTS_TYPE_UNSPECIFIED_VAL;
	err = bt_ots_obj_add(ots, &param);
	object_being_created = NULL;
	if (err < 0) {
		printk("Failed to add an object to OTS (err: %d)\n", err);
		return err;
	}

	return 0;
}

void main(void)
{
	int err;

	printk("Starting Bluetooth Peripheral OTS example\n");

	err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}

	printk("Bluetooth initialized\n");

	err = ots_init();
	if (err) {
		printk("Failed to init OTS (err:%d)\n", err);
		return;
	}

	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
			      sd, ARRAY_SIZE(sd));
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}

	printk("Advertising successfully started\n");
}
