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

/**
 * @file
 *   This file implements the OpenThread module initialization and state change handling.
 *
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_openthread_platform, CONFIG_OPENTHREAD_PLATFORM_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/version.h>
#include <zephyr/sys/check.h>

#include "platform/platform-zephyr.h"

#include <openthread.h>
#include <openthread_utils.h>

#include <openthread/child_supervision.h>
#include <openthread/cli.h>
#include <openthread/ip6.h>
#include <openthread/link.h>
#include <openthread/link_raw.h>
#include <openthread/ncp.h>
#include <openthread/message.h>
#include <openthread/platform/diag.h>
#include <openthread/tasklet.h>
#include <openthread/thread.h>
#include <openthread/dataset.h>
#include <openthread/joiner.h>
#include <openthread-system.h>
#include <utils/uart.h>

#if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)
#include <openthread/nat64.h>
#endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */

#define OT_STACK_SIZE (CONFIG_OPENTHREAD_THREAD_STACK_SIZE)

#if defined(CONFIG_OPENTHREAD_THREAD_PREEMPTIVE)
#define OT_PRIORITY K_PRIO_PREEMPT(CONFIG_OPENTHREAD_THREAD_PRIORITY)
#else
#define OT_PRIORITY K_PRIO_COOP(CONFIG_OPENTHREAD_THREAD_PRIORITY)
#endif

#if defined(CONFIG_OPENTHREAD_NETWORK_NAME)
#define OT_NETWORK_NAME CONFIG_OPENTHREAD_NETWORK_NAME
#else
#define OT_NETWORK_NAME ""
#endif

#if defined(CONFIG_OPENTHREAD_CHANNEL)
#define OT_CHANNEL CONFIG_OPENTHREAD_CHANNEL
#else
#define OT_CHANNEL 0
#endif

#if defined(CONFIG_OPENTHREAD_PANID)
#define OT_PANID CONFIG_OPENTHREAD_PANID
#else
#define OT_PANID 0
#endif

#if defined(CONFIG_OPENTHREAD_XPANID)
#define OT_XPANID CONFIG_OPENTHREAD_XPANID
#else
#define OT_XPANID ""
#endif

#if defined(CONFIG_OPENTHREAD_NETWORKKEY)
#define OT_NETWORKKEY CONFIG_OPENTHREAD_NETWORKKEY
#else
#define OT_NETWORKKEY ""
#endif

#if defined(CONFIG_OPENTHREAD_JOINER_PSKD)
#define OT_JOINER_PSKD CONFIG_OPENTHREAD_JOINER_PSKD
#else
#define OT_JOINER_PSKD ""
#endif

#if defined(CONFIG_OPENTHREAD_PLATFORM_INFO)
#define OT_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO
#else
#define OT_PLATFORM_INFO ""
#endif

#if defined(CONFIG_OPENTHREAD_POLL_PERIOD)
#define OT_POLL_PERIOD CONFIG_OPENTHREAD_POLL_PERIOD
#else
#define OT_POLL_PERIOD 0
#endif

#define ZEPHYR_PACKAGE_NAME "Zephyr"
#define PACKAGE_VERSION     KERNEL_VERSION_STRING

static void openthread_process(struct k_work *work);

/* Global variables to store the OpenThread module context */
static otInstance *openthread_instance;
static sys_slist_t openthread_state_change_cbs = SYS_SLIST_STATIC_INIT(openthread_state_change_cbs);
static struct k_work_q openthread_work_q;

static K_WORK_DEFINE(openthread_work, openthread_process);
static K_MUTEX_DEFINE(openthread_lock);
K_KERNEL_STACK_DEFINE(ot_stack_area, OT_STACK_SIZE);

k_tid_t openthread_thread_id_get(void)
{
	return (k_tid_t)&openthread_work_q.thread;
}

static int ncp_hdlc_send(const uint8_t *buf, uint16_t len)
{
	otError err = OT_ERROR_NONE;

	err = otPlatUartSend(buf, len);
	if (err != OT_ERROR_NONE) {
		return 0;
	}

	return len;
}

static void openthread_process(struct k_work *work)
{
	ARG_UNUSED(work);

	openthread_mutex_lock();

	while (otTaskletsArePending(openthread_instance)) {
		otTaskletsProcess(openthread_instance);
	}

	otSysProcessDrivers(openthread_instance);

	openthread_mutex_unlock();
}

static void ot_joiner_start_handler(otError error, void *context)
{
	ARG_UNUSED(context);

	if (error != OT_ERROR_NONE) {
		LOG_ERR("Join failed [%d]", error);
	} else {
		LOG_INF("Join success");
		error = otThreadSetEnabled(openthread_instance, true);
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to start the OpenThread network [%d]", error);
		}
	}
}

static bool ot_setup_default_configuration(void)
{
	otExtendedPanId xpanid = {0};
	otNetworkKey networkKey = {0};
	otError error = OT_ERROR_NONE;

	error = otThreadSetNetworkName(openthread_instance, OT_NETWORK_NAME);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to set %s [%d]", "network name", error);
		return false;
	}

	error = otLinkSetChannel(openthread_instance, OT_CHANNEL);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to set %s [%d]", "channel", error);
		return false;
	}

	error = otLinkSetPanId(openthread_instance, OT_PANID);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to set %s [%d]", "PAN ID", error);
		return false;
	}

	if (bytes_from_str(xpanid.m8, 8, (char *)OT_XPANID) != 0) {
		LOG_ERR("Failed to parse extended PAN ID");
		return false;
	}
	error = otThreadSetExtendedPanId(openthread_instance, &xpanid);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to set %s [%d]", "ext PAN ID", error);
		return false;
	}

	if (strlen(OT_NETWORKKEY)) {
		if (bytes_from_str(networkKey.m8, OT_NETWORK_KEY_SIZE, (char *)OT_NETWORKKEY) !=
		    0) {
			LOG_ERR("Failed to parse network key");
			return false;
		}
		error = otThreadSetNetworkKey(openthread_instance, &networkKey);
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to set %s [%d]", "network key", error);
			return false;
		}
	}

	return true;
}

static void ot_state_changed_handler(uint32_t flags, void *context)
{
	ARG_UNUSED(context);

	struct openthread_state_changed_callback *entry, *next;

	bool is_up = otIp6IsEnabled(openthread_instance);

	LOG_INF("State changed! Flags: 0x%08" PRIx32 " Current role: %s Ip6: %s", flags,
		otThreadDeviceRoleToString(otThreadGetDeviceRole(openthread_instance)),
		(is_up ? "up" : "down"));

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&openthread_state_change_cbs, entry, next, node) {
		if (entry->otCallback != NULL) {
			entry->otCallback(flags, entry->user_data);
		}
	}
}

void otTaskletsSignalPending(otInstance *instance)
{
	ARG_UNUSED(instance);

	int error = k_work_submit_to_queue(&openthread_work_q, &openthread_work);

	if (error < 0) {
		LOG_ERR("Failed to submit work to queue, error: %d", error);
	}
}

void otSysEventSignalPending(void)
{
	otTaskletsSignalPending(NULL);
}

int openthread_state_changed_callback_register(struct openthread_state_changed_callback *cb)
{
	CHECKIF(cb == NULL || cb->otCallback == NULL) {
		return -EINVAL;
	}

	openthread_mutex_lock();
	sys_slist_append(&openthread_state_change_cbs, &cb->node);
	openthread_mutex_unlock();

	return 0;
}

int openthread_state_changed_callback_unregister(struct openthread_state_changed_callback *cb)
{
	bool removed = false;

	CHECKIF(cb == NULL) {
		return -EINVAL;
	}

	openthread_mutex_lock();
	removed = sys_slist_find_and_remove(&openthread_state_change_cbs, &cb->node);
	openthread_mutex_unlock();

	if (!removed) {
		return -EALREADY;
	}

	return 0;
}

struct otInstance *openthread_get_default_instance(void)
{
	__ASSERT(openthread_instance, "OT instance is not initialized");
	return openthread_instance;
}

int openthread_init(void)
{
	struct k_work_queue_config q_cfg = {
		.name = "openthread",
		.no_yield = true,
	};
	otError error = OT_ERROR_NONE;

	/* Prevent multiple initializations */
	if (openthread_instance) {
		return 0;
	}

	/* Start work queue for the OpenThread module */
	k_work_queue_start(&openthread_work_q, ot_stack_area,
			   K_KERNEL_STACK_SIZEOF(ot_stack_area),
			   OT_PRIORITY, &q_cfg);

	openthread_mutex_lock();

	otSysInit(0, NULL);
	openthread_instance = otInstanceInitSingle();

	__ASSERT(openthread_instance, "OT instance initialization failed");

	if (IS_ENABLED(CONFIG_OPENTHREAD_SHELL)) {
		platformShellInit(openthread_instance);
	}

	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
		error = otPlatUartEnable();
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to enable UART: [%d]", error);
		}

		otNcpHdlcInit(openthread_instance, ncp_hdlc_send);
	} else {
		otIp6SetReceiveFilterEnabled(openthread_instance, true);

#if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)

		otIp4Cidr nat64_cidr;

		if (otIp4CidrFromString(CONFIG_OPENTHREAD_NAT64_CIDR, &nat64_cidr) ==
		    OT_ERROR_NONE) {
			if (otNat64SetIp4Cidr(openthread_instance, &nat64_cidr) != OT_ERROR_NONE) {
				LOG_ERR("Incorrect NAT64 CIDR");
				return -EIO;
			}
		} else {
			LOG_ERR("Failed to parse NAT64 CIDR");
			return -EIO;
		}
#endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */

		error = otSetStateChangedCallback(openthread_instance, &ot_state_changed_handler,
						  NULL);
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Could not set state changed callback: %d", error);
			return -EIO;
		}
	}

	openthread_mutex_unlock();

	(void)k_work_submit_to_queue(&openthread_work_q, &openthread_work);

	return error == OT_ERROR_NONE ? 0 : -EIO;
}

int openthread_run(void)
{
	openthread_mutex_lock();
	otError error = OT_ERROR_NONE;

	LOG_INF("OpenThread version: %s", otGetVersionString());

	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
		LOG_DBG("OpenThread co-processor.");
		goto exit;
	}

	error = otIp6SetEnabled(openthread_instance, true);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to set %s [%d]", "IPv6 support", error);
		goto exit;
	}

	/* Sleepy End Device specific configuration. */
	if (IS_ENABLED(CONFIG_OPENTHREAD_MTD_SED)) {
		otLinkModeConfig ot_mode = otThreadGetLinkMode(openthread_instance);

		/* A SED should always attach the network as a SED to indicate
		 * increased buffer requirement to a parent.
		 */
		ot_mode.mRxOnWhenIdle = false;

		error = otThreadSetLinkMode(openthread_instance, ot_mode);
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to set %s [%d]", "link mode", error);
			goto exit;
		}

		error = otLinkSetPollPeriod(openthread_instance, OT_POLL_PERIOD);
		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to set %s [%d]", "poll period", error);
			goto exit;
		}
	}

	/* Configure Child Supervision and MLE Child timeouts. */
	otChildSupervisionSetInterval(openthread_instance,
				      CONFIG_OPENTHREAD_CHILD_SUPERVISION_INTERVAL);
	otChildSupervisionSetCheckTimeout(openthread_instance,
					  CONFIG_OPENTHREAD_CHILD_SUPERVISION_CHECK_TIMEOUT);
	otThreadSetChildTimeout(openthread_instance, CONFIG_OPENTHREAD_MLE_CHILD_TIMEOUT);

	if (otDatasetIsCommissioned(openthread_instance)) {
		/* OpenThread already has dataset stored - skip the
		 * configuration.
		 */
		LOG_DBG("OpenThread already commissioned.");
	} else if (IS_ENABLED(CONFIG_OPENTHREAD_JOINER_AUTOSTART)) {
		/* No dataset - initiate network join procedure. */
		LOG_DBG("Starting OpenThread join procedure.");

		error = otJoinerStart(openthread_instance, OT_JOINER_PSKD, NULL,
				      ZEPHYR_PACKAGE_NAME, OT_PLATFORM_INFO, PACKAGE_VERSION, NULL,
				      &ot_joiner_start_handler, NULL);

		if (error != OT_ERROR_NONE) {
			LOG_ERR("Failed to start joiner [%d]", error);
		}

		goto exit;
	} else {
		/* No dataset - load the default configuration. */
		LOG_DBG("Loading OpenThread default configuration.");

		if (!ot_setup_default_configuration()) {
			goto exit;
		}
	}

	LOG_INF("Network name: %s", otThreadGetNetworkName(openthread_instance));

	/* Start the network. */
	error = otThreadSetEnabled(openthread_instance, true);
	if (error != OT_ERROR_NONE) {
		LOG_ERR("Failed to start the OpenThread network [%d]", error);
	}

exit:

	openthread_mutex_unlock();

	return error == OT_ERROR_NONE ? 0 : -EIO;
}

int openthread_stop(void)
{
	otError error = OT_ERROR_NONE;

	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
		return 0;
	}

	openthread_mutex_lock();

	error = otThreadSetEnabled(openthread_instance, false);
	if (error == OT_ERROR_INVALID_STATE) {
		LOG_DBG("Openthread interface was not up [%d]", error);
	}

	openthread_mutex_unlock();

	return 0;
}

void openthread_set_receive_cb(openthread_receive_cb cb, void *context)
{
	__ASSERT(cb != NULL, "Receive callback is not set");
	__ASSERT(openthread_instance != NULL, "OpenThread instance is not initialized");

	if (!IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
		openthread_mutex_lock();
		otIp6SetReceiveCallback(openthread_instance, cb, context);

#if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)
		otNat64SetReceiveIp4Callback(openthread_instance, cb, context);
#endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */

		openthread_mutex_unlock();
	}
}

void openthread_mutex_lock(void)
{
	(void)k_mutex_lock(&openthread_lock, K_FOREVER);
}

int openthread_mutex_try_lock(void)
{
	return k_mutex_lock(&openthread_lock, K_NO_WAIT);
}

void openthread_mutex_unlock(void)
{
	(void)k_mutex_unlock(&openthread_lock);
}

#ifdef CONFIG_OPENTHREAD_SYS_INIT
static int openthread_sys_init(void)
{
	int error = openthread_init();

	if (error == 0) {
#ifndef CONFIG_OPENTHREAD_MANUAL_START
		error = openthread_run();
#endif
	}

	return error;
}

SYS_INIT(openthread_sys_init, POST_KERNEL, CONFIG_OPENTHREAD_SYS_INIT_PRIORITY);
#endif /* CONFIG_OPENTHREAD_SYS_INIT */
