/* main.c - Application main entry point */

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

#include <zephyr/types.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <misc/printk.h>
#include <linker/sections.h>

#include <tc_util.h>

#include <net/ethernet.h>
#include <net/buf.h>
#include <net/net_ip.h>
#include <net/net_if.h>
#include <net/net_context.h>

#define NET_LOG_ENABLED 1
#include "net_private.h"
#include "ipv6.h"
#include "icmpv6.h"
#include "nbr.h"
#include "rpl.h"

#if defined(CONFIG_NET_DEBUG_RPL)
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif

static struct net_context *udp_ctx;

static struct in6_addr in6addr_my = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					  0, 0, 0, 0, 0, 0, 0, 0x1 } } };
static struct in6_addr peer_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					 0, 0, 0, 0, 0, 0, 0, 0x2 } } };
static struct in6_addr in6addr_ll = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
					  0, 0, 0, 0xf2, 0xaa, 0x29, 0x02,
					  0x04 } } };
static struct in6_addr in6addr_mcast = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					     0, 0, 0, 0, 0, 0, 0, 0x1 } } };

static struct net_linkaddr_storage lladdr_src_storage = {
	.addr = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
	.len = NET_LINK_ADDR_MAX_LENGTH
};
static struct net_linkaddr lladdr_src = {
	.addr = lladdr_src_storage.addr,
	.len = NET_LINK_ADDR_MAX_LENGTH
};

static bool test_failed;
static bool data_failure;
static bool feed_data; /* feed data back to IP stack */

static int msg_sending;
static int expected_icmpv6 = NET_ICMPV6_RPL;

static struct k_sem wait_data;

static struct net_if_link_cb link_cb;
static bool link_cb_called;

#define WAIT_TIME 250

struct net_rpl_test {
	u8_t mac_addr[sizeof(struct net_eth_addr)];
	struct net_linkaddr ll_addr;
};

int net_rpl_dev_init(struct device *dev)
{
	return 0;
}

static u8_t *net_rpl_get_mac(struct device *dev)
{
	struct net_rpl_test *rpl = dev->driver_data;

	if (rpl->mac_addr[2] == 0x00) {
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		rpl->mac_addr[0] = 0x00;
		rpl->mac_addr[1] = 0x00;
		rpl->mac_addr[2] = 0x5E;
		rpl->mac_addr[3] = 0x00;
		rpl->mac_addr[4] = 0x53;
		rpl->mac_addr[5] = sys_rand32_get();
	}

	return rpl->mac_addr;
}

static void net_rpl_iface_init(struct net_if *iface)
{
	u8_t *mac = net_rpl_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
			     NET_LINK_ETHERNET);
}

static void set_pkt_ll_addr(struct device *dev, struct net_pkt *pkt)
{
	struct net_rpl_test *rpl = dev->driver_data;

	struct net_linkaddr *src = net_pkt_ll_src(pkt);
	struct net_linkaddr *dst = net_pkt_ll_dst(pkt);

	dst->len = lladdr_src.len;
	dst->addr = lladdr_src.addr;

	src->len = sizeof(rpl->mac_addr);
	src->addr = rpl->mac_addr;
}

#define NET_ICMP_HDR(pkt) ((struct net_icmp_hdr *)net_pkt_icmp_data(pkt))

static int tester_send(struct net_if *iface, struct net_pkt *pkt)
{
	if (!pkt->frags) {
		TC_ERROR("No data to send!\n");
		return -ENODATA;
	}

	set_pkt_ll_addr(iface->dev, pkt);

	/* By default we assume that the test is ok */
	data_failure = false;

	if (feed_data) {
		net_pkt_ll_swap(pkt);

		if (net_recv_data(iface, pkt) < 0) {
			TC_ERROR("Data receive failed.");
			net_pkt_unref(pkt);
			test_failed = true;
		}

		k_sem_give(&wait_data);

		return 0;
	}

	DBG("pkt %p to be sent len %lu\n", pkt, net_pkt_get_len(pkt));

#if defined(CONFIG_NET_DEBUG_RPL)
	net_hexdump_frags("recv", pkt, false);
#endif

	if (NET_ICMP_HDR(pkt)->type != expected_icmpv6) {
		DBG("ICMPv6 type %d, expected %d\n",
		    NET_ICMP_HDR(pkt)->type, expected_icmpv6);

		data_failure = true;
	}

	/* If we are not sending what is expected, then mark it as a failure
	 */
	if (msg_sending) {
		if (msg_sending != NET_ICMP_HDR(pkt)->code) {
			DBG("Received code %d, expected %d\n",
			    NET_ICMP_HDR(pkt)->code, msg_sending);

			data_failure = true;
		} else {
			/* Pass sent DIO message back to us */
			if (msg_sending == NET_RPL_DODAG_INFO_OBJ) {
				net_pkt_ll_swap(pkt);

				if (!net_recv_data(iface, pkt)) {
					/* We must not unref the msg,
					 * as it should be unfreed by
					 * the upper stack.
					 */
					goto out;
				}
			}
		}
	}

	net_pkt_unref(pkt);

out:
	if (data_failure) {
		test_failed = true;
	}

	msg_sending = 0;

	k_sem_give(&wait_data);

	return 0;
}

struct net_rpl_test net_rpl_data;

static struct net_if_api net_rpl_if_api = {
	.init = net_rpl_iface_init,
	.send = tester_send,
};

#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)

NET_DEVICE_INIT(net_rpl_test, "net_rpl_test",
		net_rpl_dev_init, &net_rpl_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		&net_rpl_if_api, _ETH_L2_LAYER,
		_ETH_L2_CTX_TYPE, 127);

static void send_link_cb(struct net_if *iface, struct net_linkaddr *lladdr,
			 int status)
{
	link_cb_called = true;
}

static bool test_init(void)
{
	struct net_if_addr *ifaddr;
	struct net_if_mcast_addr *maddr;
	struct net_if *iface = net_if_get_default();
	struct net_rpl_dag *dag;

	if (!iface) {
		TC_ERROR("Interface is NULL\n");
		return false;
	}

	ifaddr = net_if_ipv6_addr_add(iface, &in6addr_my,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		TC_ERROR("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&in6addr_my));
		return false;
	}

	/* For testing purposes we need to set the adddresses preferred */
	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv6_addr_add(iface, &in6addr_ll,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		TC_ERROR("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&in6addr_ll));
		return false;
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	net_ipv6_addr_create(&in6addr_mcast, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);

	maddr = net_if_ipv6_maddr_add(iface, &in6addr_mcast);
	if (!maddr) {
		TC_ERROR("Cannot add multicast IPv6 address %s\n",
		       net_sprint_ipv6_addr(&in6addr_mcast));
		return false;
	}

	/* The semaphore is there to wait the data to be received. */
	k_sem_init(&wait_data, 0, UINT_MAX);

	net_if_register_link_cb(&link_cb, send_link_cb);

	/* Creating a new RPL DAG */
	net_rpl_set_root(iface, NET_RPL_DEFAULT_INSTANCE, &in6addr_my);
	dag = net_rpl_get_any_dag();
	net_rpl_set_prefix(iface, dag, &in6addr_my, 64);

	return true;
}

static bool net_ctx_create(void)
{
	int ret;

	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP,
			      &udp_ctx);
	if (ret != 0) {
		TC_ERROR("Context create IPv6 UDP test failed (%d vs %d)\n",
		       ret, 0);
		return false;
	}

	return true;
}

static bool test_rpl_mcast_addr(void)
{
	struct in6_addr rpl_mcast = { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0,
					  0, 0, 0, 0, 0, 0, 0, 0x1a } } };
	struct in6_addr addr;
	bool ret;

	ret = net_rpl_is_ipv6_addr_mcast(&rpl_mcast);
	if (!ret) {
		TC_ERROR("RPL multicast address check failed.\n");
		return false;
	}

	net_rpl_create_mcast_address(&addr);

	ret = net_rpl_is_ipv6_addr_mcast(&addr);
	if (!ret) {
		TC_ERROR("Generated RPL multicast address check failed.\n");
		return false;
	}

	return true;
}

static bool test_dio_dummy_input(void)
{
	struct net_pkt *pkt;
	struct net_buf *frag;
	int ret;

	pkt = net_pkt_get_tx(udp_ctx, K_FOREVER);
	frag = net_pkt_get_data(udp_ctx, K_FOREVER);

	net_pkt_frag_add(pkt, frag);

	msg_sending = NET_RPL_DODAG_INFO_OBJ;

	set_pkt_ll_addr(net_if_get_default()->dev, pkt);

	ret = net_icmpv6_input(pkt, NET_ICMPV6_RPL, msg_sending);
	if (!ret) {
		TC_ERROR("%d: Callback in %s not called properly\n", __LINE__,
			 __func__);
		return false;
	}

	data_failure = false;
	k_sem_take(&wait_data, WAIT_TIME);

	if (data_failure) {
		TC_ERROR("%d: Unexpected ICMPv6 code received\n", __LINE__);
		return false;
	}

	data_failure = false;

	return true;
}

static bool test_dis_sending(void)
{
	struct net_if *iface;
	int ret;

	iface = net_if_get_default();

	msg_sending = NET_RPL_DODAG_SOLICIT;

	ret = net_rpl_dis_send(NULL, iface);
	if (ret) {
		TC_ERROR("%d: Cannot send DIS (%d)\n", __LINE__, ret);
		return false;
	}

	k_sem_take(&wait_data, WAIT_TIME);

	if (data_failure) {
		data_failure = false;
		TC_ERROR("%d: Unexpected ICMPv6 code received\n", __LINE__);
		return false;
	}

	data_failure = false;

	return true;
}

static bool test_dao_sending_fail(void)
{
	struct net_if *iface = NULL, *iface_def;
	struct in6_addr *prefix, *prefix2;
	struct net_rpl_instance instance = {
		.instance_id = 42,
	};
	struct net_rpl_dag dag = {
		.dag_id = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0, 0, 0x2 } } },
		.instance = &instance,
	};
	struct net_rpl_parent parent = {
		.dag = &dag,
	};
	int ret;

	iface_def = net_if_get_default();
	prefix2 = net_if_ipv6_get_global_addr(&iface_def);

	prefix = net_if_ipv6_get_global_addr(&iface);
	if (!prefix) {
		TC_ERROR("Will not send DAO as no global address was found.");
		return false;
	}

	if (iface != iface_def) {
		TC_ERROR("Network interface mismatch (%p vs %p)\n",
			 iface, iface_def);
		return false;
	}

	if (prefix != prefix2) {
		TC_ERROR("Network interface mismatch or not set (%p vs %p)\n",
			 prefix, prefix2);
		return false;
	}

	msg_sending = NET_RPL_DEST_ADV_OBJ;

	/* The sending should fail at this point because the neighbor
	 * is not suppose to be found in neighbor cache.
	 */
	ret = net_rpl_dao_send(iface, &parent, prefix, 100);
	if (!ret) {
		TC_ERROR("DAO send succeed but should not have\n");
		return false;
	}

	return true;
}

static bool net_test_send_ns(void)
{
	struct net_if *iface = net_if_get_default();
	struct net_nbr *nbr;
	int ret;

	/* As we are sending a node reachability NS (RFC 4861 ch 4.3),
	 * we need to add the neighbor to the cache, otherwise we cannot
	 * send a NS with unicast destination address.
	 */
	nbr = net_ipv6_nbr_add(iface,
			       &in6addr_my,
			       &iface->link_addr,
			       false,
			       NET_IPV6_NBR_STATE_REACHABLE);
	if (!nbr) {
		TC_ERROR("Cannot add to neighbor cache\n");
		return false;
	}

	ret = net_ipv6_send_ns(iface,
			       NULL,
			       &peer_addr,
			       &in6addr_my,
			       &in6addr_my,
			       false);
	if (ret < 0) {
		TC_ERROR("Cannot send NS (%d)\n", ret);
		return false;
	}

	return true;
}

static bool net_test_nbr_lookup_ok(void)
{
	struct net_linkaddr_storage *llstorage;
	struct net_nbr *nbr;

	nbr = net_ipv6_nbr_lookup(net_if_get_default(),
				  &peer_addr);
	if (!nbr) {
		TC_ERROR("Neighbor %s not found in cache\n",
			 net_sprint_ipv6_addr(&peer_addr));
		return false;
	}

	/* Set the ll address in the neighbor so that following
	 * tests work ok.
	 */
	llstorage = net_nbr_get_lladdr(nbr->idx);
	memcpy(llstorage->addr, lladdr_src.addr, lladdr_src.len);
	llstorage->len = lladdr_src.len;

	DBG("[%d] Neighbor %s lladdr %s\n", nbr->idx,
	    net_sprint_ipv6_addr(&peer_addr),
	    net_sprint_ll_addr(llstorage->addr, llstorage->len));

	net_ipv6_nbr_data(nbr)->state = NET_IPV6_NBR_STATE_REACHABLE;

	return true;
}

static bool populate_nbr_cache(void)
{
	struct net_nbr *nbr;

	msg_sending = NET_ICMPV6_NS;
	feed_data = true;
	data_failure = false;

	if (!net_test_send_ns()) {
		return false;
	}

	k_sem_take(&wait_data, WAIT_TIME);

	feed_data = false;

	if (data_failure) {
		data_failure = false;
		return false;
	}

	data_failure = false;

	nbr = net_ipv6_nbr_add(net_if_get_default(),
			       &peer_addr,
			       &lladdr_src,
			       false,
			       NET_IPV6_NBR_STATE_REACHABLE);
	if (!nbr) {
		TC_ERROR("Cannot add peer to neighbor cache\n");
		return false;
	}

	if (!net_test_nbr_lookup_ok()) {
		return false;
	}

	return true;
}

#if 0
/* This test is currently disabled as it needs more TLC */
static bool test_dao_sending_ok(void)
{
	struct net_if *iface = NULL, *iface_def;
	struct in6_addr *prefix, *prefix2;
	struct net_rpl_dag *dag;
	int ret;

	iface_def = net_if_get_default();
	prefix2 = net_if_ipv6_get_global_addr(&iface_def);

	prefix = net_if_ipv6_get_global_addr(&iface);
	if (!prefix) {
		TC_ERROR("Will not send DAO as no global address was found.");
		return false;
	}

	if (iface != iface_def) {
		TC_ERROR("Network interface mismatch (%p vs %p)\n",
			 iface, iface_def);
		return false;
	}

	if (prefix != prefix2) {
		TC_ERROR("Network interface mismatch or not set (%p vs %p)\n",
			 prefix, prefix2);
		return false;
	}

	msg_sending = NET_RPL_DEST_ADV_OBJ;

	net_rpl_set_root(iface_def, NET_RPL_DEFAULT_INSTANCE, prefix);

	dag = net_rpl_get_any_dag();

	if (!net_rpl_set_prefix(iface, dag, &prefix, 64)) {
		TC_ERROR("Failed to create a new RPL DAG\n");
		return false;
	}

	ret = net_rpl_dao_send(iface, dag->preferred_parent, prefix, 100);
	if (ret) {
		TC_ERROR("%d: Cannot send DAO (%d)\n", __LINE__, ret);
		return false;
	}

	k_sem_take(&wait_data, WAIT_TIME);

	if (data_failure) {
		data_failure = false;
		TC_ERROR("%d: Unexpected ICMPv6 code received\n", __LINE__);
		return false;
	}

	data_failure = false;

	return true;
}

/* This test fails currently, it needs more TLC */
static bool test_link_cb(void)
{
	link_cb_called = false;
	msg_sending = 0;
	expected_icmpv6 = NET_ICMPV6_NS;

	net_test_send_ns();

	k_sem_take(&wait_data, WAIT_TIME);

	/* Restore earlier expected value, by default we only accept
	 * RPL ICMPv6 messages.
	 */
	expected_icmpv6 = NET_ICMPV6_RPL;

	if (!link_cb_called) {
		TC_ERROR("%d: Link cb not called\n", __LINE__);
		return false;
	}

	return true;
}
#endif

static bool test_dio_receive_dest(void)
{
	struct net_if *iface = NULL, *iface_def;
	struct in6_addr *prefix, *prefix2;
	struct net_rpl_instance instance = {
		.instance_id = CONFIG_NET_RPL_DEFAULT_INSTANCE,
		.mop = NET_RPL_MOP_STORING_NO_MULTICAST,
		.min_hop_rank_inc = 100,
		.ocp = 1, /* MRH OF */
	};
	struct net_rpl_dag dag = {
		.dag_id = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0, 0, 0x1 } } },
		.instance = &instance,
		.prefix_info = {
			.prefix = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0 } } },
			.length = 64,
		},
		.version = 1,
		.rank = 2,
	};
	int ret;

	instance.current_dag = &dag;

	iface_def = net_if_get_default();
	prefix2 = net_if_ipv6_get_global_addr(&iface_def);

	prefix = net_if_ipv6_get_global_addr(&iface);
	if (!prefix) {
		TC_ERROR("Will not send DAO as no global address was found.");
		return false;
	}

	if (iface != iface_def) {
		TC_ERROR("Network interface mismatch (%p vs %p)\n",
			 iface, iface_def);
		return false;
	}

	if (prefix != prefix2) {
		TC_ERROR("Network interface mismatch or not set (%p vs %p)\n",
			 prefix, prefix2);
		return false;
	}

	msg_sending = NET_RPL_DODAG_INFO_OBJ;

	ret = net_rpl_dio_send(iface, &instance, &peer_addr, &in6addr_my);
	if (ret) {
		TC_ERROR("%d: Cannot send DIO (%d)\n", __LINE__, ret);
		return false;
	}

	k_sem_take(&wait_data, WAIT_TIME);

	if (data_failure) {
		data_failure = false;
		TC_ERROR("%d: Unexpected ICMPv6 code received\n", __LINE__);
		return false;
	}

	data_failure = false;

	return true;
}

static const struct {
	const char *name;
	bool (*func)(void);
} tests[] = {
	{ "test init", test_init },
	{ "test ctx create", net_ctx_create },
	{ "RPL multicast address test", test_rpl_mcast_addr },
	{ "DIO input handler test", test_dio_dummy_input },
	{ "DIS sending", test_dis_sending },
	{ "DAO sending fail", test_dao_sending_fail },
	{ "Populate neighbor cache", populate_nbr_cache },
	{ "DIO receive dest set", test_dio_receive_dest },
#if 0
	{ "Link cb test", test_link_cb },
	{ "DAO sending ok", test_dao_sending_ok },
	{ "DIO receive dest not set", test_dio_receive },
#endif
};

void main(void)
{
	int count, pass;

	for (count = 0, pass = 0; count < ARRAY_SIZE(tests); count++) {
		TC_START(tests[count].name);
		test_failed = false;
		if (!tests[count].func() || test_failed) {
			TC_END(FAIL, "failed\n");
		} else {
			TC_END(PASS, "passed\n");
			pass++;
		}
	}

	TC_END_REPORT(((pass != ARRAY_SIZE(tests)) ? TC_FAIL : TC_PASS));
}
