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

#include <zephyr/kernel.h>
#include <zephyr/ipc/ipc_service.h>
#include <zephyr/logging/log_link.h>
#include <zephyr/logging/log_multidomain_helper.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(link_ipc);

void log_multidomain_link_on_error(struct log_multidomain_link *link_remote, int err)
{
	link_remote->status = err;
}

void log_multidomain_link_on_started(struct log_multidomain_link *link_remote, int err)
{
	link_remote->status = err;

	if (err == 0) {
		link_remote->ready = true;
	}
}

void log_multidomain_link_on_recv_cb(struct log_multidomain_link *link_remote,
				const void *data, size_t len)
{
	struct log_multidomain_msg *msg = (struct log_multidomain_msg *)data;

	if (msg->status != Z_LOG_MULTIDOMAIN_STATUS_OK) {
		link_remote->status = -EIO;
		goto exit;
	} else {
		link_remote->status = 0;
	}

	switch (msg->id) {
	case Z_LOG_MULTIDOMAIN_ID_MSG:
		z_log_msg_enqueue(link_remote->link,
				  msg->data.log_msg.data,
				  len - offsetof(struct log_multidomain_msg, data));
		return;
	case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT:
		link_remote->dst.count = msg->data.domain_cnt.count;
		break;
	case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT:
		link_remote->dst.count = msg->data.source_cnt.count;
		break;
	case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME:
	{
		size_t slen = MIN(len - 1, *link_remote->dst.name.len - 1);

		*link_remote->dst.name.len = len - 1;
		memcpy(link_remote->dst.name.dst, msg->data.domain_name.name, slen);
		link_remote->dst.name.dst[slen] = '\0';
		break;
	}
	case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME:
	{
		size_t slen = MIN(len - 1, *link_remote->dst.name.len - 1);

		*link_remote->dst.name.len = len - 1;
		memcpy(link_remote->dst.name.dst, msg->data.source_name.name, slen);
		link_remote->dst.name.dst[slen] = '\0';
		break;
	}
	case Z_LOG_MULTIDOMAIN_ID_GET_LEVELS:
		link_remote->dst.levels.level = msg->data.levels.level;
		link_remote->dst.levels.runtime_level = msg->data.levels.runtime_level;
		break;
	case Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL:
		link_remote->dst.set_runtime_level.level = msg->data.set_rt_level.runtime_level;
		break;
	case Z_LOG_MULTIDOMAIN_ID_DROPPED:
		return;
	case Z_LOG_MULTIDOMAIN_ID_READY:
		break;
	default:
		__ASSERT(0, "Unexpected message");
		return;
	}

exit:
	k_sem_give(&link_remote->rdy_sem);
}

static int getter_msg_process(struct log_multidomain_link *link_remote,
			      struct log_multidomain_msg *msg, size_t msg_size)
{
	int err;

	err = link_remote->transport_api->send(link_remote, msg, msg_size);
	if (err < 0) {
		return err;
	}

	err = k_sem_take(&link_remote->rdy_sem, K_MSEC(1000));
	if (err < 0) {
		return err;
	}

	return (link_remote->status == Z_LOG_MULTIDOMAIN_STATUS_OK) ? 0 : -EIO;
}

static int link_remote_get_domain_count(struct log_multidomain_link *link_remote,
					uint16_t *cnt)
{
	int err;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT,
	};

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	*cnt = link_remote->dst.count;

	return 0;
}

static int link_remote_get_source_count(struct log_multidomain_link *link_remote,
					      uint32_t domain_id,
					      uint16_t *cnt)
{
	int err;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT,
		.data = { .source_cnt = { .domain_id = domain_id } }
	};

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	*cnt = link_remote->dst.count;

	return 0;
}

static int link_remote_ready(struct log_multidomain_link *link_remote)
{
	int err;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_READY
	};

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	return 0;
}

static int link_remote_initiate(const struct log_link *link,
				struct log_link_config *config)
{
	struct log_multidomain_link *link_remote = link->ctx;

	link_remote->link = link;
	k_sem_init(&link_remote->rdy_sem, 0, 1);

	return link_remote->transport_api->init(link_remote);
}

static int link_remote_activate(const struct log_link *link)
{
	struct log_multidomain_link *link_remote = link->ctx;
	int err;

	if (!link_remote->ready) {
		return -EINPROGRESS;
	}

	if (link_remote->status != 0) {
		return link_remote->status;
	}

	uint16_t cnt;

	err = link_remote_get_domain_count(link_remote, &cnt);
	if (err < 0) {
		return err;
	}

	if (cnt > ARRAY_SIZE(link->ctrl_blk->source_cnt)) {
		__ASSERT(0, "Number of domains not supported.");
		return -ENOMEM;
	}

	link->ctrl_blk->domain_cnt = cnt;
	for (int i = 0; i < link->ctrl_blk->domain_cnt; i++) {
		err = link_remote_get_source_count(link_remote, i, &cnt);
		if (err < 0) {
			return err;
		}

		link->ctrl_blk->source_cnt[i] = cnt;
	}

	err = link_remote_ready(link_remote);

	return err;
}

static int link_remote_get_domain_name(const struct log_link *link,
					uint32_t domain_id,
					char *name, uint32_t *length)
{
	struct log_multidomain_link *link_remote = link->ctx;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME,
		.data = { .domain_name = { .domain_id = domain_id } }
	};
	int err;


	link_remote->dst.name.dst = name;
	link_remote->dst.name.len = length;

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	return 0;
}

static int link_remote_get_source_name(const struct log_link *link,
					uint32_t domain_id, uint16_t source_id,
					char *name, size_t *length)
{
	struct log_multidomain_link *link_remote = link->ctx;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME,
		.data = {
			.source_name = {
				.domain_id = domain_id,
				.source_id = source_id
			}
		}
	};
	int err;

	link_remote->dst.name.dst = name;
	link_remote->dst.name.len = length;

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	return 0;
}

static int link_remote_get_levels(const struct log_link *link,
				   uint32_t domain_id, uint16_t source_id,
				   uint8_t *level, uint8_t *runtime_level)
{
	struct log_multidomain_link *link_remote = link->ctx;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_GET_LEVELS,
		.data = {
			.levels = {
				.domain_id = domain_id,
				.source_id = source_id
			}
		}
	};
	int err;

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	if (level) {
		*level = link_remote->dst.levels.level;
	}
	if (runtime_level) {
		*runtime_level = link_remote->dst.levels.runtime_level;
	}

	return 0;
}

static int link_remote_set_runtime_level(const struct log_link *link,
					 uint32_t domain_id, uint16_t source_id,
					 uint8_t level)
{
	struct log_multidomain_link *link_remote = link->ctx;
	struct log_multidomain_msg msg = {
		.id = Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL,
		.data = {
			.set_rt_level = {
				.domain_id = domain_id,
				.source_id = source_id,
				.runtime_level = level
			}
		}
	};
	int err;

	err = getter_msg_process(link_remote, &msg, sizeof(msg));
	if (err < 0) {
		return err;
	}

	return 0;
}

struct log_link_api log_multidomain_link_api = {
	.initiate = link_remote_initiate,
	.activate = link_remote_activate,
	.get_domain_name = link_remote_get_domain_name,
	.get_source_name = link_remote_get_source_name,
	.get_levels = link_remote_get_levels,
	.set_runtime_level = link_remote_set_runtime_level
};
