/*
 * 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/zephyr.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 % 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 % 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");
}
