/*
 * 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;
	struct net_if_mcast_addr *zmaddr;

	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))));
		}

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

		if (zmaddr &&
		    !(net_if_ipv6_maddr_is_joined(zmaddr) ||
		      net_ipv6_is_addr_mcast_iface(
				(struct in6_addr *)(&maddress->mAddress)) ||
		      net_ipv6_is_addr_mcast_link_all_nodes(
				(struct in6_addr *)(&maddress->mAddress)))) {

			net_if_ipv6_maddr_join(zmaddr);
		}
	}
}

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);
		}
	}
}
