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

#include <zephyr.h>
#include <device.h>
#include <string.h>
#include <drivers/mbox.h>

#include <ipc/ipc_service_backend.h>
#include "ipc_icmsg.h"

#define DT_DRV_COMPAT	zephyr_ipc_icmsg
#define CB_BUF_SIZE	CONFIG_IPC_SERVICE_BACKEND_ICMSG_CB_BUF_SIZE

static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b,
				0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34};
BUILD_ASSERT(sizeof(magic) <= CB_BUF_SIZE);
BUILD_ASSERT(CB_BUF_SIZE <= UINT16_MAX);

struct backend_data_t {
	/* Tx/Rx buffers. */
	struct icmsg_buf *tx_ib;
	struct icmsg_buf *rx_ib;

	/* Backend ops for an endpoint. */
	const struct ipc_ept_cfg *cfg;

	/* General */
	struct k_work mbox_work;
	atomic_t state;
};

struct backend_config_t {
	uintptr_t tx_shm_addr;
	uintptr_t rx_shm_addr;
	size_t tx_shm_size;
	size_t rx_shm_size;
	struct mbox_channel mbox_tx;
	struct mbox_channel mbox_rx;
};


static void mbox_callback_process(struct k_work *item)
{
	struct backend_data_t *dev_data = CONTAINER_OF(item, struct backend_data_t, mbox_work);
	uint8_t cb_buffer[CB_BUF_SIZE] __aligned(4);

	atomic_t state = atomic_get(&dev_data->state);
	int len = icmsg_buf_read(dev_data->rx_ib, cb_buffer, CB_BUF_SIZE);

	__ASSERT_NO_MSG(len <= CB_BUF_SIZE);

	if (len == -EAGAIN) {
		__ASSERT_NO_MSG(false);
		(void)k_work_submit(&dev_data->mbox_work);
		return;
	} else if (len <= 0) {
		return;
	}

	if (state == ICMSG_STATE_READY) {
		if (dev_data->cfg->cb.received) {
			dev_data->cfg->cb.received(cb_buffer, len, dev_data->cfg->priv);
		}

		/* Reading with NULL buffer to know if there are data in the
		 * buffer to be read.
		 */
		len = icmsg_buf_read(dev_data->rx_ib, NULL, 0);
		if (len > 0) {
			(void)k_work_submit(&dev_data->mbox_work);
		}
	} else {
		__ASSERT_NO_MSG(state == ICMSG_STATE_BUSY);
		if (len != sizeof(magic) || memcmp(magic, cb_buffer, len)) {
			__ASSERT_NO_MSG(false);
			return;
		}

		if (dev_data->cfg->cb.bound) {
			dev_data->cfg->cb.bound(dev_data->cfg->priv);
		}

		atomic_set(&dev_data->state, ICMSG_STATE_READY);
	}
}

static void mbox_callback(const struct device *instance, uint32_t channel,
			  void *user_data, struct mbox_msg *msg_data)
{
	struct backend_data_t *dev_data = user_data;

	(void)k_work_submit(&dev_data->mbox_work);
}

static int mbox_init(const struct device *instance)
{
	const struct backend_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;
	int err;

	k_work_init(&dev_data->mbox_work, mbox_callback_process);

	err = mbox_register_callback(&conf->mbox_rx, mbox_callback, dev_data);
	if (err != 0) {
		return err;
	}

	return mbox_set_enabled(&conf->mbox_rx, 1);
}

static int register_ept(const struct device *instance, void **token,
			const struct ipc_ept_cfg *cfg)
{
	const struct backend_config_t *conf = instance->config;
	struct backend_data_t *dev_data = instance->data;
	struct ipc_ept *ep = (struct ipc_ept *)token;
	int ret;

	if (!atomic_cas(&dev_data->state, ICMSG_STATE_OFF, ICMSG_STATE_BUSY)) {
		/* Already registered. This backend supports single ep. */
		return -EALREADY;
	}

	ep->instance = instance;
	dev_data->cfg = cfg;

	ret = mbox_init(instance);
	if (ret) {
		return ret;
	}

	ret = icmsg_buf_write(dev_data->tx_ib, magic, sizeof(magic));
	if (ret < sizeof(magic)) {
		__ASSERT_NO_MSG(ret == sizeof(magic));
		return ret;
	}

	ret = mbox_send(&conf->mbox_tx, NULL);
	if (ret) {
		return ret;
	}

	ret = icmsg_buf_read(dev_data->rx_ib, NULL, 0);
	if (ret > 0) {
		(void)k_work_submit(&dev_data->mbox_work);
	}

	return 0;
}

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

	if (atomic_get(&dev_data->state) != ICMSG_STATE_READY) {
		return -EBUSY;
	}

	/* Empty message is not allowed */
	if (len == 0) {
		return -ENODATA;
	}

	ret = icmsg_buf_write(dev_data->tx_ib, msg, len);
	if (ret < 0) {
		return ret;
	} else if (ret < len) {
		return -EBADMSG;
	}

	__ASSERT_NO_MSG(conf->mbox_tx.dev != NULL);

	return mbox_send(&conf->mbox_tx, NULL);
}

const static struct ipc_service_backend backend_ops = {
	.register_endpoint = register_ept,
	.send = send,
};

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

	__ASSERT_NO_MSG(conf->tx_shm_size > sizeof(struct icmsg_buf));

	dev_data->tx_ib = icmsg_buf_init((void *)conf->tx_shm_addr, conf->tx_shm_size);
	dev_data->rx_ib = (void *)conf->rx_shm_addr;

	return 0;
}

#define DEFINE_BACKEND_DEVICE(i)						\
	static const struct backend_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)
