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

#include <zephyr/kernel.h>
#include <zephyr/device.h>

#include <zephyr/ipc/ipc_service.h>

#define STACKSIZE	(4096)
#define PRIORITY	K_PRIO_PREEMPT(2)

K_THREAD_STACK_DEFINE(ipc0A_stack, STACKSIZE);
K_THREAD_STACK_DEFINE(ipc0B_stack, STACKSIZE);
K_THREAD_STACK_DEFINE(ipc1_stack, STACKSIZE);

static volatile uint8_t ipc0A_received_data;
static volatile uint8_t ipc0B_received_data;
static volatile uint8_t ipc1_received_data;

static K_SEM_DEFINE(ipc0A_bound_sem, 0, 1);
static K_SEM_DEFINE(ipc0B_bound_sem, 0, 1);
static K_SEM_DEFINE(ipc1_bound_sem, 0, 1);

static K_SEM_DEFINE(ipc0A_data_sem, 0, 1);
static K_SEM_DEFINE(ipc0B_data_sem, 0, 1);
static K_SEM_DEFINE(ipc1_data_sem, 0, 1);

/*
 * ==> THREAD 0A (IPC instance 0 - endpoint A) <==
 */

static void ipc0A_ept_bound(void *priv)
{
	k_sem_give(&ipc0A_bound_sem);
}

static void ipc0A_ept_recv(const void *data, size_t len, void *priv)
{
	ipc0A_received_data = *((uint8_t *) data);

	k_sem_give(&ipc0A_data_sem);
}

static struct ipc_ept_cfg ipc0A_ept_cfg = {
	.name = "ipc0A",
	.cb = {
		.bound    = ipc0A_ept_bound,
		.received = ipc0A_ept_recv,
	},
};

static void ipc0A_entry(void *dummy0, void *dummy1, void *dummy2)
{
	ARG_UNUSED(dummy0);
	ARG_UNUSED(dummy1);
	ARG_UNUSED(dummy2);

	const struct device *ipc0_instance;
	unsigned char message = 0;
	struct ipc_ept ipc0A_ept;
	int ret;

	printk("IPC-service HOST [INST 0 - ENDP A] demo started\n");

	ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));

	ret = ipc_service_open_instance(ipc0_instance);
	if (ret < 0 && ret != -EALREADY) {
		printk("ipc_service_open_instance() failure\n");
		return;
	}

	/*
	 * Wait 1 sec to give the opportunity to the SECONDARY core to register
	 * the endpoint first
	 */

	k_sleep(K_MSEC(1000));

	ret = ipc_service_register_endpoint(ipc0_instance, &ipc0A_ept, &ipc0A_ept_cfg);
	if (ret < 0) {
		printf("ipc_service_register_endpoint() failure\n");
		return;
	}

	k_sem_take(&ipc0A_bound_sem, K_FOREVER);

	while (message < 100) {
		ret = ipc_service_send(&ipc0A_ept, &message, sizeof(message));
		if (ret < 0) {
			printk("send_message(%d) failed with ret %d\n", message, ret);
			break;
		}

		k_sem_take(&ipc0A_data_sem, K_FOREVER);
		message = ipc0A_received_data;

		printk("HOST [0A]: %d\n", message);
		message++;
	}

	printk("IPC-service HOST [INST 0 - ENDP A] demo ended.\n");
}
K_THREAD_DEFINE(ipc0A_thread_id, STACKSIZE, ipc0A_entry, NULL, NULL, NULL, PRIORITY, 0, 0);

/*
 * ==> THREAD 0B (IPC instance 0 - endpoint B) <==
 */

static void ipc0B_ept_bound(void *priv)
{
	k_sem_give(&ipc0B_bound_sem);
}

static void ipc0B_ept_recv(const void *data, size_t len, void *priv)
{
	ipc0B_received_data = *((uint8_t *) data);

	k_sem_give(&ipc0B_data_sem);
}

static struct ipc_ept_cfg ipc0B_ept_cfg = {
	.name = "ipc0B",
	.cb = {
		.bound    = ipc0B_ept_bound,
		.received = ipc0B_ept_recv,
	},
};

static void ipc0B_entry(void *dummy0, void *dummy1, void *dummy2)
{
	ARG_UNUSED(dummy0);
	ARG_UNUSED(dummy1);
	ARG_UNUSED(dummy2);

	const struct device *ipc0_instance;
	unsigned char message = 0;
	struct ipc_ept ipc0B_ept;
	int ret;

	printk("IPC-service HOST [INST 0 - ENDP B] demo started\n");

	ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));

	ret = ipc_service_open_instance(ipc0_instance);
	if (ret < 0 && ret != -EALREADY) {
		printk("ipc_service_open_instance() failure\n");
		return;
	}

	ret = ipc_service_register_endpoint(ipc0_instance, &ipc0B_ept, &ipc0B_ept_cfg);
	if (ret < 0) {
		printf("ipc_service_register_endpoint() failure\n");
		return;
	}

	k_sem_take(&ipc0B_bound_sem, K_FOREVER);

	while (message < 100) {
		ret = ipc_service_send(&ipc0B_ept, &message, sizeof(message));
		if (ret < 0) {
			printk("send_message(%d) failed with ret %d\n", message, ret);
			break;
		}

		k_sem_take(&ipc0B_data_sem, K_FOREVER);
		message = ipc0B_received_data;

		printk("HOST [0B]: %d\n", message);
		message++;
	}

	printk("IPC-service HOST [INST 0 - ENDP B] demo ended.\n");
}
K_THREAD_DEFINE(ipc0B_thread_id, STACKSIZE, ipc0B_entry, NULL, NULL, NULL, PRIORITY, 0, 0);

/*
 * ==> THREAD 1 (IPC instance 1) <==
 *
 * NOTE: This instance is using the NOCOPY copability of the backend.
 */

static struct ipc_ept ipc1_ept;

static void ipc1_ept_bound(void *priv)
{
	k_sem_give(&ipc1_bound_sem);
}

static void ipc1_ept_recv(const void *data, size_t len, void *priv)
{
	ipc1_received_data = *((uint8_t *) data);

	k_sem_give(&ipc1_data_sem);
}

static struct ipc_ept_cfg ipc1_ept_cfg = {
	.name = "ipc1",
	.cb = {
		.bound    = ipc1_ept_bound,
		.received = ipc1_ept_recv,
	},
};

static void ipc1_entry(void *dummy0, void *dummy1, void *dummy2)
{
	ARG_UNUSED(dummy0);
	ARG_UNUSED(dummy1);
	ARG_UNUSED(dummy2);

	const struct device *ipc1_instance;
	unsigned char message = 0;
	int ret;

	printk("IPC-service HOST [INST 1] demo started\n");

	ipc1_instance = DEVICE_DT_GET(DT_NODELABEL(ipc1));

	ret = ipc_service_open_instance(ipc1_instance);
	if (ret < 0 && ret != -EALREADY) {
		printk("ipc_service_open_instance() failure\n");
		return;
	}

	ret = ipc_service_register_endpoint(ipc1_instance, &ipc1_ept, &ipc1_ept_cfg);
	if (ret < 0) {
		printf("ipc_service_register_endpoint() failure\n");
		return;
	}

	k_sem_take(&ipc1_bound_sem, K_FOREVER);

	/*
	 * Wait 1 sec to start sending simultaneously with other threads
	 * the endpoint first
	 */

	k_sleep(K_MSEC(1000));

	while (message < 100) {
		ret = ipc_service_send(&ipc1_ept, &message, sizeof(message));
		if (ret < 0) {
			printk("send_message(%d) failed with ret %d\n", message, ret);
			break;
		}

		k_sem_take(&ipc1_data_sem, K_FOREVER);
		message = ipc1_received_data;

		printk("HOST [1]: %d\n", message);
		message++;
	}

	printk("IPC-service HOST [INST 1] demo ended.\n");
}
K_THREAD_DEFINE(ipc1_thread_id, STACKSIZE, ipc1_entry, NULL, NULL, NULL, PRIORITY, 0, 0);
