/*
 * 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>
#include <hal/nrf_reset.h>
#include <string.h>

#include "common.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(host, LOG_LEVEL_INF);


#define DT_DRV_COMPAT	zephyr_ipc_icmsg

K_SEM_DEFINE(bound_sem, 0, 1);
static unsigned char expected_message = 'A';
static size_t expected_len = PACKET_SIZE_START;

static void ep_bound(void *priv)
{
	k_sem_give(&bound_sem);
	LOG_INF("Ep bounded");
}

static void ep_recv(const void *data, size_t len, void *priv)
{
	struct data_packet *packet = (struct data_packet *)data;

	__ASSERT(packet->data[0] == expected_message, "Unexpected message. Expected %c, got %c",
		expected_message, packet->data[0]);
	__ASSERT(len == expected_len, "Unexpected length. Expected %zu, got %zu",
		expected_len, len);

	expected_message++;
	expected_len++;

	if (expected_message > 'Z') {
		expected_message = 'A';
	}

	if (expected_len > sizeof(struct data_packet)) {
		expected_len = PACKET_SIZE_START;
	}
}

static int send_for_time(struct ipc_ept *ep, const int64_t sending_time_ms)
{
	struct data_packet msg = {.data[0] = 'a'};
	size_t mlen = PACKET_SIZE_START;
	size_t bytes_sent = 0;
	int ret = 0;

	LOG_INF("Perform sends for %lld [ms]", sending_time_ms);

	int64_t start = k_uptime_get();

	while ((k_uptime_get() - start) < sending_time_ms) {
		ret = ipc_service_send(ep, &msg, mlen);
		if (ret == -ENOMEM) {
			/* No space in the buffer. Retry. */
			continue;
		} else if (ret < 0) {
			LOG_ERR("Failed to send (%c) failed with ret %d", msg.data[0], ret);
			break;
		}

		msg.data[0]++;
		if (msg.data[0] > 'z') {
			msg.data[0] = 'a';
		}

		bytes_sent += mlen;
		mlen++;

		if (mlen > sizeof(struct data_packet)) {
			mlen = PACKET_SIZE_START;
		}

		k_usleep(1);
	}

	LOG_INF("Sent %zu [Bytes] over %lld [ms]", bytes_sent, sending_time_ms);

	return ret;
}

static struct ipc_ept_cfg ep_cfg = {
	.cb = {
		.bound    = ep_bound,
		.received = ep_recv,
	},
};

int main(void)
{
	const struct device *ipc0_instance;
	struct ipc_ept ep;
	int ret;

	LOG_INF("IPC-service HOST demo started");

	ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));

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

	ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg);
	if (ret < 0) {
		LOG_ERR("ipc_service_register_endpoint() failure");
		return ret;
	}

	k_sem_take(&bound_sem, K_FOREVER);

	ret = send_for_time(&ep, SENDING_TIME_MS);
	if (ret < 0) {
		LOG_ERR("send_for_time() failure");
		return ret;
	}

	LOG_INF("Wait 500ms. Let net core finish its sends");
	k_msleep(500);

	LOG_INF("Stop network core");
	nrf_reset_network_force_off(NRF_RESET, true);

	LOG_INF("Reset IPC service");

	ret = ipc_service_deregister_endpoint(&ep);
	if (ret != 0) {
		LOG_ERR("ipc_service_register_endpoint() failure");
		return ret;
	}

	/* Reset message and expected message value and len. */
	expected_message = 'A';
	expected_len = PACKET_SIZE_START;

	/* Reset bound sem. */
	ret = k_sem_init(&bound_sem, 0, 1);
	if (ret != 0) {
		LOG_ERR("k_sem_init() failure");
		return ret;
	}

	uintptr_t tx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(0, tx_region));
	uintptr_t tx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(0, tx_region));
	uintptr_t rx_shm_size = DT_REG_SIZE(DT_INST_PHANDLE(0, rx_region));
	uintptr_t rx_shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(0, rx_region));

	LOG_INF("Clean shared memory");

	memset((void *)tx_shm_addr, 0, tx_shm_size);
	memset((void *)rx_shm_addr, 0, rx_shm_size);

	ret = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg);
	if (ret != 0) {
		LOG_INF("ipc_service_register_endpoint() failure");
		return ret;
	}

	LOG_INF("Run network core");
	nrf_reset_network_force_off(NRF_RESET, false);

	k_sem_take(&bound_sem, K_FOREVER);

	ret = send_for_time(&ep, SENDING_TIME_MS);
	if (ret < 0) {
		LOG_ERR("send_for_time() failure");
		return ret;
	}

	LOG_INF("IPC-service HOST demo ended");

	return 0;
}
