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

#include <logging/log.h>
LOG_MODULE_DECLARE(net_l2_openthread, CONFIG_OPENTHREAD_L2_LOG_LEVEL);

#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/openthread.h>

#include <openthread/ip6.h>
#include <openthread/thread.h>

#include "openthread_utils.h"

#define ALOC16_MASK 0xfc

static bool is_anycast_locator(const otNetifAddress *address)
{
	return address->mAddress.mFields.m16[4] == htons(0x0000) &&
	       address->mAddress.mFields.m16[5] == htons(0x00ff) &&
	       address->mAddress.mFields.m16[6] == htons(0xfe00) &&
	       address->mAddress.mFields.m8[14] == ALOC16_MASK;
}

static bool is_mesh_local(struct openthread_context *context,
			  const uint8_t *address)
{
	const otMeshLocalPrefix *ml_prefix =
				otThreadGetMeshLocalPrefix(context->instance);

	return (memcmp(address, ml_prefix->m8, sizeof(ml_prefix)) == 0);
}

int pkt_list_add(struct openthread_context *context, struct net_pkt *pkt)
{
	uint16_t i_idx = context->pkt_list_in_idx;

	if (context->pkt_list_full) {
		return -ENOMEM;
	}

	i_idx++;
	if (i_idx == CONFIG_OPENTHREAD_PKT_LIST_SIZE) {
		i_idx = 0U;
	}

	if (i_idx == context->pkt_list_out_idx) {
		context->pkt_list_full = 1U;
	}

	context->pkt_list[context->pkt_list_in_idx].pkt = pkt;
	context->pkt_list_in_idx = i_idx;

	return 0;
}

void pkt_list_remove_first(struct openthread_context *context)
{
	uint16_t idx = context->pkt_list_in_idx;

	if (idx == 0U) {
		idx = CONFIG_OPENTHREAD_PKT_LIST_SIZE - 1;
	} else {
		idx--;
	}
	context->pkt_list_in_idx = idx;

	if (context->pkt_list_full) {
		context->pkt_list_full = 0U;
	}
}

struct net_pkt *pkt_list_peek(struct openthread_context *context)
{
	if ((context->pkt_list_in_idx == context->pkt_list_out_idx) &&
	    (!context->pkt_list_full)) {

		return NULL;
	}
	return context->pkt_list[context->pkt_list_out_idx].pkt;
}

void pkt_list_remove_last(struct openthread_context *context)
{
	if ((context->pkt_list_in_idx == context->pkt_list_out_idx) &&
	    (!context->pkt_list_full)) {

		return;
	}

	context->pkt_list_out_idx++;
	if (context->pkt_list_out_idx == CONFIG_OPENTHREAD_PKT_LIST_SIZE) {
		context->pkt_list_out_idx = 0U;
	}

	context->pkt_list_full = 0U;
}

void add_ipv6_addr_to_zephyr(struct openthread_context *context)
{
	const otNetifAddress *address;
	struct net_if_addr *if_addr;

	for (address = otIp6GetUnicastAddresses(context->instance);
	     address; address = address->mNext) {

		if (address->mRloc || is_anycast_locator(address)) {
			continue;
		}

		if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
			char buf[NET_IPV6_ADDR_LEN];

			NET_DBG("Adding %s",
				log_strdup(net_addr_ntop(AF_INET6,
				       (struct in6_addr *)(&address->mAddress),
				       buf, sizeof(buf))));
		}

		/* Thread and SLAAC are clearly AUTOCONF, handle
		 * manual/NCP addresses in the same way
		 */
		if ((address->mAddressOrigin == OT_ADDRESS_ORIGIN_THREAD) ||
		    (address->mAddressOrigin == OT_ADDRESS_ORIGIN_SLAAC)) {
			if_addr = net_if_ipv6_addr_add(
					context->iface,
					(struct in6_addr *)(&address->mAddress),
					NET_ADDR_AUTOCONF, 0);
		} else if (address->mAddressOrigin ==
			   OT_ADDRESS_ORIGIN_DHCPV6) {
			if_addr = net_if_ipv6_addr_add(
					context->iface,
					(struct in6_addr *)(&address->mAddress),
					NET_ADDR_DHCP, 0);
		} else if (address->mAddressOrigin ==
			  OT_ADDRESS_ORIGIN_MANUAL) {
			if_addr = net_if_ipv6_addr_add(
					context->iface,
					(struct in6_addr *)(&address->mAddress),
					NET_ADDR_MANUAL, 0);
		} else {
			NET_ERR("Unknown OpenThread address origin ignored.");
			continue;
		}

		if (if_addr == NULL) {
			NET_ERR("Cannot add OpenThread unicast address");
			continue;
		}

		if_addr->is_mesh_local = is_mesh_local(
					context, address->mAddress.mFields.m8);
	}
}

void add_ipv6_addr_to_ot(struct openthread_context *context)
{
	struct net_if *iface = context->iface;
	struct otNetifAddress addr;
	struct net_if_ipv6 *ipv6;
	int i;

	(void)memset(&addr, 0, sizeof(addr));

	if (net_if_config_ipv6_get(iface, &ipv6) < 0) {
		NET_DBG("Cannot allocate IPv6 address");
		return;
	}

	/* save the last added IP address for this interface */
	for (i = NET_IF_MAX_IPV6_ADDR - 1; i >= 0; i--) {
		if (ipv6->unicast[i].is_used) {
			memcpy(&addr.mAddress,
			       &ipv6->unicast[i].address.in6_addr,
			       sizeof(addr.mAddress));
			break;
		}
	}

	ipv6->unicast[i].is_mesh_local = is_mesh_local(
			context, ipv6->unicast[i].address.in6_addr.s6_addr);

	addr.mValid = true;
	addr.mPreferred = true;
	addr.mPrefixLength = 64;

	if (ipv6->unicast[i].addr_type == NET_ADDR_AUTOCONF) {
		addr.mAddressOrigin = OT_ADDRESS_ORIGIN_SLAAC;
	} else if (ipv6->unicast[i].addr_type == NET_ADDR_DHCP) {
		addr.mAddressOrigin = OT_ADDRESS_ORIGIN_DHCPV6;
	} else if (ipv6->unicast[i].addr_type == NET_ADDR_MANUAL) {
		addr.mAddressOrigin = OT_ADDRESS_ORIGIN_MANUAL;
	} else {
		NET_ERR("Unknown address type");
		return;
	}

	openthread_api_mutex_lock(context);
	otIp6AddUnicastAddress(context->instance, &addr);
	openthread_api_mutex_unlock(context);

	if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
		char buf[NET_IPV6_ADDR_LEN];

		NET_DBG("Added %s",
			log_strdup(net_addr_ntop(AF_INET6,
						 &addr.mAddress, buf,
						 sizeof(buf))));
	}
}

void add_ipv6_maddr_to_ot(struct openthread_context *context)
{
	struct otIp6Address addr;
	struct net_if_ipv6 *ipv6;
	int i;

	if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) {
		NET_DBG("Cannot allocate IPv6 address");
		return;
	}

	/* save the last added IP address for this interface */
	for (i = NET_IF_MAX_IPV6_MADDR - 1; i >= 0; i--) {
		if (ipv6->mcast[i].is_used) {
			memcpy(&addr,
			       &ipv6->mcast[i].address.in6_addr,
			       sizeof(addr));
			break;
		}
	}

	openthread_api_mutex_lock(context);
	otIp6SubscribeMulticastAddress(context->instance, &addr);
	openthread_api_mutex_unlock(context);

	if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
		char buf[NET_IPV6_ADDR_LEN];

		NET_DBG("Added multicast %s",
			log_strdup(net_addr_ntop(AF_INET6, &addr,
						 buf, sizeof(buf))));
	}
}

void add_ipv6_maddr_to_zephyr(struct openthread_context *context)
{
	const otNetifMulticastAddress *maddress;

	for (maddress = otIp6GetMulticastAddresses(context->instance);
	     maddress; maddress = maddress->mNext) {
		if (net_if_ipv6_maddr_lookup(
				(struct in6_addr *)(&maddress->mAddress),
				&context->iface) != NULL) {
			continue;
		}

		if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
			char buf[NET_IPV6_ADDR_LEN];

			NET_DBG("Adding multicast %s",
				log_strdup(net_addr_ntop(AF_INET6,
							 (struct in6_addr *)
							 (&maddress->mAddress),
							 buf, sizeof(buf))));
		}

		net_if_ipv6_maddr_add(context->iface,
				      (struct in6_addr *)(&maddress->mAddress));
	}
}

void rm_ipv6_addr_from_zephyr(struct openthread_context *context)
{
	struct in6_addr *ot_addr;
	struct net_if_addr *zephyr_addr;
	struct net_if_ipv6 *ipv6;
	int i;

	if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) {
		NET_DBG("Cannot find IPv6 address");
		return;
	}

	for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) {
		const otNetifAddress *address;
		bool used = false;

		zephyr_addr = &ipv6->unicast[i];
		if (!zephyr_addr->is_used) {
			continue;
		}

		for (address = otIp6GetUnicastAddresses(context->instance);
		     address; address = address->mNext) {

			ot_addr = (struct in6_addr *)(&address->mAddress);
			if (net_ipv6_addr_cmp(ot_addr,
					      &zephyr_addr->address.in6_addr)) {

				used = true;
				break;
			}
		}
		if (!used) {
			if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
				char buf[NET_IPV6_ADDR_LEN];

				NET_DBG("Removing %s",
					log_strdup(net_addr_ntop(AF_INET6,
					      &zephyr_addr->address.in6_addr,
					      buf, sizeof(buf))));
			}

			net_if_ipv6_addr_rm(context->iface,
					    &zephyr_addr->address.in6_addr);
		}
	}
}

void rm_ipv6_maddr_from_zephyr(struct openthread_context *context)
{
	struct in6_addr *ot_addr;
	struct net_if_mcast_addr *zephyr_addr;
	struct net_if_ipv6 *ipv6;
	int i;

	if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) {
		NET_DBG("Cannot find IPv6 address");
		return;
	}

	for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) {
		const otNetifMulticastAddress *maddress;
		bool used = false;

		zephyr_addr = &ipv6->mcast[i];
		if (!zephyr_addr->is_used) {
			continue;
		}

		for (maddress = otIp6GetMulticastAddresses(context->instance);
		     maddress; maddress = maddress->mNext) {

			ot_addr = (struct in6_addr *)(&maddress->mAddress);
			if (net_ipv6_addr_cmp(ot_addr,
					      &zephyr_addr->address.in6_addr)) {

				used = true;
				break;
			}
		}
		if (!used) {
			if (CONFIG_OPENTHREAD_L2_LOG_LEVEL == LOG_LEVEL_DBG) {
				char buf[NET_IPV6_ADDR_LEN];

				NET_DBG("Removing multicast %s",
					log_strdup(net_addr_ntop(AF_INET6,
					      &zephyr_addr->address.in6_addr,
					      buf, sizeof(buf))));
			}

			net_if_ipv6_maddr_rm(context->iface,
					     &zephyr_addr->address.in6_addr);
		}
	}
}
