/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#if 1
#define SYS_LOG_DOMAIN "rpl-br/rpl"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

#include <zephyr.h>
#include <stdio.h>
#include <stdlib.h>

#include <net/net_ip.h>
#include "../../../subsys/net/ip/rpl.h"

#include "config.h"

static struct {
	struct in6_addr dag_id;
	u8_t dag_init_version;
	bool dag_has_version;

	struct in6_addr prefix;
	u8_t prefix_len;
} rpl;

static bool br_join_dag(struct net_rpl_dio *dio)
{
	static u8_t last_version;

	if (net_ipv6_addr_cmp(&dio->dag_id, &rpl.dag_id)) {
		if (rpl.dag_init_version != dio->version &&
		    last_version != dio->version) {
			NET_DBG("Me root, DIO version %d instance %d",
				dio->version, dio->instance_id);
			last_version = dio->version;
		}

		if (dio->version > NET_RPL_LOLLIPOP_CIRCULAR_REGION) {
			rpl.dag_init_version = dio->version;
			rpl.dag_has_version = true;
		}
#if CONFIG_SYS_LOG_NET_LEVEL > 3
	} else {
		char me[NET_IPV6_ADDR_LEN];
		char other[NET_IPV6_ADDR_LEN];

		net_addr_ntop(AF_INET6, &dio->dag_id, other,
			      NET_IPV6_ADDR_LEN);
		net_addr_ntop(AF_INET6, &rpl.dag_id, me, NET_IPV6_ADDR_LEN);

		NET_DBG("Other root %s, me %s, DIO version %d instance %d",
			other, me, dio->version, dio->instance_id);
#endif
	}

	return 0;
}

bool setup_rpl(struct net_if *iface, const char *addr_prefix)
{
	char prefix[NET_IPV6_ADDR_LEN + 1];
	struct net_rpl_dag *dag;
	char *slash;
	bool ret;

	/* As the addr_prefix is Kconfig option we need to copy it to temporary
	 * buffer in order to be able to manipulate it.
	 */
	memset(prefix, 0, sizeof(prefix));
	memcpy(prefix, addr_prefix, min(strlen(addr_prefix),
					NET_IPV6_ADDR_LEN));

	slash = strstr(prefix, "/");
	if (!slash) {
		rpl.prefix_len = 64;
	} else {
		*slash = '\0';
		rpl.prefix_len = atoi(slash + 1);
	}

	if (rpl.prefix_len == 0) {
		NET_ERR("Invalid prefix length %s", slash + 1);
		return false;
	}

	if (net_addr_pton(AF_INET6, prefix, &rpl.prefix) < 0) {
		NET_ERR("Invalid IPv6 prefix %s", prefix);
		return false;
	}

	net_rpl_set_join_callback(br_join_dag);

	if (rpl.dag_has_version) {
		net_rpl_lollipop_increment(&rpl.dag_init_version);

		dag = net_rpl_set_root_with_version(iface,
			CONFIG_NET_RPL_DEFAULT_INSTANCE, &rpl.dag_id,
			rpl.dag_init_version);
	} else {
		dag = net_rpl_set_root(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE,
				       &rpl.prefix);
	}
	if (!dag) {
		NET_ERR("Cannot set root node");
		return false;
	}

	net_rpl_dag_set_grounded_status(dag, 1);

	ret = net_rpl_set_prefix(iface, dag, &rpl.prefix, rpl.prefix_len);
	if (!ret) {
		NET_ERR("Cannot set prefix %s/%d", prefix, rpl.prefix_len);
		return false;
	}

#if CONFIG_SYS_LOG_NET_LEVEL > 3
	{
		char out[NET_IPV6_ADDR_LEN];

		if (net_addr_ntop(AF_INET6, &rpl.prefix, out,
				  NET_IPV6_ADDR_LEN)) {
			if (rpl.dag_has_version) {
				NET_DBG("New RPL dag %s/%d version %u created",
					out, rpl.prefix_len,
					rpl.dag_init_version);
			} else {
				NET_DBG("New RPL dag %s/%d created", out,
					rpl.prefix_len);
			}
		}
	}
#endif

	return true;
}
