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

#include <zephyr.h>
#include <ipc/ipc_service.h>
#include <device.h>
#include <logging/log.h>

#include "nrf_802154_spinel_backend_callouts.h"
#include "nrf_802154_serialization_error.h"
#include "../../spinel_base/spinel.h"
#include "../../src/include/nrf_802154_spinel.h"

#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE_NAME spinel_ipc_backend
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#define IPC_BOUND_TIMEOUT_IN_MS K_MSEC(1000)

static K_SEM_DEFINE(edp_bound_sem, 0, 1);
static struct ipc_ept ept;

static void endpoint_bound(void *priv)
{
	k_sem_give(&edp_bound_sem);
}

static void endpoint_received(const void *data, size_t len, void *priv)
{
	LOG_DBG("Received message of %u bytes.", len);

	nrf_802154_spinel_encoded_packet_received(data, len);
}

static struct ipc_ept_cfg ept_cfg = {
	.name = "nrf_802154_spinel",
	.cb = {
		.bound = endpoint_bound,
		.received = endpoint_received
	},
};

nrf_802154_ser_err_t nrf_802154_backend_init(void)
{
	const struct device *ipc_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
	int err;

	err = ipc_service_open_instance(ipc_instance);
	if (err < 0 && err != -EALREADY) {
		LOG_ERR("Failed to open IPC instance: %d", err);
		return NRF_802154_SERIALIZATION_ERROR_INIT_FAILED;
	}

	err = ipc_service_register_endpoint(ipc_instance, &ept, &ept_cfg);
	if (err < 0) {
		LOG_ERR("Failed to register IPC endpoint: %d", err);
		return NRF_802154_SERIALIZATION_ERROR_INIT_FAILED;
	}

	err = k_sem_take(&edp_bound_sem, IPC_BOUND_TIMEOUT_IN_MS);
	if (err < 0) {
		LOG_ERR("IPC endpoint bind timed out");
		return NRF_802154_SERIALIZATION_ERROR_INIT_FAILED;
	}

	return NRF_802154_SERIALIZATION_ERROR_OK;
}

/* Send packet thread details */
#define RING_BUFFER_LEN 16
#define SEND_THREAD_STACK_SIZE 1024

static K_SEM_DEFINE(send_sem, 0, RING_BUFFER_LEN);
K_THREAD_STACK_DEFINE(send_thread_stack, SEND_THREAD_STACK_SIZE);
struct k_thread send_thread_data;

struct ringbuffer {
	uint32_t len;
	uint8_t data[NRF_802154_SPINEL_FRAME_MAX_SIZE];
};

static struct ringbuffer ring_buffer[RING_BUFFER_LEN];
static uint8_t rd_idx;
static uint8_t wr_idx;

static uint8_t get_rb_idx_plus_1(uint8_t i)
{
	return (i + 1) % RING_BUFFER_LEN;
}

static nrf_802154_ser_err_t spinel_packet_from_thread_send(const uint8_t *data, uint32_t len)
{
	if (get_rb_idx_plus_1(wr_idx) == rd_idx) {
		LOG_ERR("No spinel buffer available to send a new packet");
		return NRF_802154_SERIALIZATION_ERROR_BACKEND_FAILURE;
	}

	LOG_DBG("Scheduling %u bytes for send thread", len);

	struct ringbuffer *buf = &ring_buffer[wr_idx];

	wr_idx = get_rb_idx_plus_1(wr_idx);
	buf->len = len;
	memcpy(buf->data, data, len);

	k_sem_give(&send_sem);
	return (nrf_802154_ser_err_t)len;
}

static void spinel_packet_send_thread_fn(void *arg1, void *arg2, void *arg3)
{
	LOG_DBG("Spinel backend send thread started");
	while (true) {
		k_sem_take(&send_sem, K_FOREVER);
		struct ringbuffer *buf = &ring_buffer[rd_idx];
		uint32_t expected_ret = buf->len;

		LOG_DBG("Sending %u bytes from send thread", buf->len);
		int ret = ipc_service_send(&ept, buf->data, buf->len);

		rd_idx = get_rb_idx_plus_1(rd_idx);

		if (ret != expected_ret) {
			nrf_802154_ser_err_data_t err = {
				.reason = NRF_802154_SERIALIZATION_ERROR_BACKEND_FAILURE,
			};

			nrf_802154_serialization_error(&err);
		}
	}
}

K_THREAD_DEFINE(spinel_packet_send_thread, SEND_THREAD_STACK_SIZE,
		spinel_packet_send_thread_fn, NULL, NULL, NULL, K_PRIO_COOP(0), 0, 0);

nrf_802154_ser_err_t nrf_802154_spinel_encoded_packet_send(const void *p_data,
							   size_t      data_len)
{
	if (k_is_in_isr()) {
		return spinel_packet_from_thread_send(p_data, data_len);
	}

	LOG_DBG("Sending %u bytes directly", data_len);
	int ret = ipc_service_send(&ept, p_data, data_len);

	return ((ret < 0) ? NRF_802154_SERIALIZATION_ERROR_BACKEND_FAILURE
			  : (nrf_802154_ser_err_t) ret);
}
