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

#include <string.h>

#include <zephyr/device.h>
#include <zephyr/ipc/icmsg.h>
#include <zephyr/ipc/icmsg_me.h>
#include <zephyr/ipc/ipc_service_backend.h>

#define DT_DRV_COMPAT	zephyr_ipc_icmsg_me_initiator

#define NUM_EP        CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NUM_EP
#define EP_NAME_LEN   CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_EP_NAME_LEN

struct backend_data_t {
	struct icmsg_me_data_t icmsg_me_data;

	struct k_mutex epts_mutex;
	icmsg_me_ept_id_t ids[NUM_EP];
};

static void bound(void *priv)
{
	const struct device *instance = priv;
	struct backend_data_t *dev_data = instance->data;

	icmsg_me_icmsg_bound(&dev_data->icmsg_me_data);
}

static void received(const void *data, size_t len, void *priv)
{
	const struct device *instance = priv;
	struct backend_data_t *dev_data = instance->data;

	const icmsg_me_ept_id_t *id = data;

	__ASSERT_NO_MSG(len > 0);

	if (*id == 0) {
		const struct ipc_ept_cfg *ept;
		int r;

		__ASSERT_NO_MSG(len > 1);

		id++;
		icmsg_me_ept_id_t ept_id = *id;

		r = icmsg_me_get_ept_cfg(&dev_data->icmsg_me_data, ept_id,
					 &ept);
		if (r < 0) {
			return;
		}

		if (ept && ept->cb.bound) {
			ept->cb.bound(ept->priv);
		}
	} else {
		icmsg_me_received_data(&dev_data->icmsg_me_data, *id,
				       data, len);
	}
}

static const struct ipc_service_cb cb = {
	.bound = bound,
	.received = received,
	.error = NULL,
};

static int open(const struct device *instance)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	return icmsg_me_open(conf, &dev_data->icmsg_me_data, &cb,
			     (void *)instance);
}

static int store_id_for_token(struct backend_data_t *data, icmsg_me_ept_id_t id,
			      void **token)
{
	int i;

	for (i = 0; i < NUM_EP; i++) {
		if (data->ids[i] == 0) {
			break;
		}
	}
	__ASSERT_NO_MSG(i < NUM_EP);
	if (i >= NUM_EP) {
		return -ENOENT;
	}

	data->ids[i] = id;
	*token = &data->ids[i];

	return 0;
}

static int register_ept(const struct device *instance, void **token,
			const struct ipc_ept_cfg *cfg)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *data = instance->data;
	int r = 0;
	icmsg_me_ept_id_t id;
	size_t name_len = strlen(cfg->name);

	if (name_len > EP_NAME_LEN) {
		return -EINVAL;
	}

	k_mutex_lock(&data->epts_mutex, K_FOREVER);

	r = icmsg_me_set_empty_ept_cfg_slot(&data->icmsg_me_data, cfg, &id);
	if (r < 0) {
		goto exit;
	}
	__ASSERT_NO_MSG(id > 0);
	if (id <= 0) {
		r = -ENOENT;
		goto reset_slot;
	}

	r = store_id_for_token(data, id, token);
	if (r < 0) {
		goto reset_slot;
	}

	uint8_t ep_disc_req[EP_NAME_LEN + 2 * sizeof(icmsg_me_ept_id_t)] = {
		0,  /* EP discovery endpoint id */
		id, /* Bound endpoint id */
	};
	memcpy(&ep_disc_req[2], cfg->name, name_len);

	icmsg_me_wait_for_icmsg_bind(&data->icmsg_me_data);

	r = icmsg_send(conf, &data->icmsg_me_data.icmsg_data, ep_disc_req,
		       2 * sizeof(icmsg_me_ept_id_t) + name_len);
	if (r < 0) {
		goto reset_slot;
	} else {
		r = 0;
	}

reset_slot:
	if (r < 0) {
		icmsg_me_reset_ept_cfg(&data->icmsg_me_data, id);
	}

exit:
	k_mutex_unlock(&data->epts_mutex);
	return r;
}

static int send(const struct device *instance, void *token,
		const void *msg, size_t len)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;
	icmsg_me_ept_id_t *id = token;

	return icmsg_me_send(conf, &dev_data->icmsg_me_data, *id, msg, len);
}

static int get_tx_buffer(const struct device *instance, void *token,
			 void **data, uint32_t *user_len, k_timeout_t wait)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	return icmsg_me_get_tx_buffer(conf, &dev_data->icmsg_me_data, data,
				      user_len, wait);
}

static int drop_tx_buffer(const struct device *instance, void *token,
			  const void *data)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	return icmsg_me_drop_tx_buffer(conf, &dev_data->icmsg_me_data, data);
}

static int send_nocopy(const struct device *instance, void *token,
			const void *data, size_t len)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;
	icmsg_me_ept_id_t *id = token;

	return icmsg_me_send_nocopy(conf, &dev_data->icmsg_me_data, *id,
				    data, len);
}

#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX
int hold_rx_buffer(const struct device *instance, void *token, void *data)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	return icmsg_me_hold_rx_buffer(conf, &dev_data->icmsg_me_data, data);
}

int release_rx_buffer(const struct device *instance, void *token, void *data)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	return icmsg_me_release_rx_buffer(conf, &dev_data->icmsg_me_data, data);
}
#endif /* CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX */

const static struct ipc_service_backend backend_ops = {
	.open_instance = open,
	.register_endpoint = register_ept,
	.send = send,

	.get_tx_buffer = get_tx_buffer,
	.drop_tx_buffer = drop_tx_buffer,
	.send_nocopy = send_nocopy,

#ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NOCOPY_RX
	.hold_rx_buffer = hold_rx_buffer,
	.release_rx_buffer = release_rx_buffer,
#endif
};

static int backend_init(const struct device *instance)
{
	const struct icmsg_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;

	k_mutex_init(&dev_data->epts_mutex);

	return icmsg_me_init(conf, &dev_data->icmsg_me_data);
}

#define DEFINE_BACKEND_DEVICE(i)						\
	static const struct icmsg_config_t backend_config_##i =			\
	{									\
		.tx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)),	\
		.tx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)),	\
		.rx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)),	\
		.rx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)),	\
		.mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx),		\
		.mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx),		\
	};									\
	static struct backend_data_t backend_data_##i;				\
										\
	DEVICE_DT_INST_DEFINE(i,						\
			 &backend_init,						\
			 NULL,							\
			 &backend_data_##i,					\
			 &backend_config_##i,					\
			 POST_KERNEL,						\
			 CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY,		\
			 &backend_ops);

DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE)
