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

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

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <device.h>
#include <init.h>
#include <sections.h>

#include <tc_util.h>

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

#define NET_LOG_ENABLED 1
#include "net_private.h"

#define TEST_BYTE_1(value, expected)				 \
	do {							 \
		char out[3];					 \
		net_byte_to_hex(out, value, 'A', true);		 \
		if (strcmp(out, expected)) {			 \
			printk("Test 0x%s failed.\n", expected); \
			return false;				 \
		}						 \
	} while (0)

#define TEST_BYTE_2(value, expected)				 \
	do {							 \
		char out[3];					 \
		net_byte_to_hex(out, value, 'a', true);		 \
		if (strcmp(out, expected)) {			 \
			printk("Test 0x%s failed.\n", expected); \
			return false;				 \
		}						 \
	} while (0)

#define TEST_LL_6(a, b, c, d, e, f, expected)				\
	do {								\
		u8_t ll[] = { a, b, c, d, e, f };			\
		if (strcmp(net_sprint_ll_addr(ll, sizeof(ll)),		\
			   expected)) {					\
			printk("Test %s failed.\n", expected);		\
			return false;					\
		}							\
	} while (0)

#define TEST_LL_8(a, b, c, d, e, f, g, h, expected)			\
	do {								\
		u8_t ll[] = { a, b, c, d, e, f, g, h };		\
		if (strcmp(net_sprint_ll_addr(ll, sizeof(ll)),		\
			   expected)) {					\
			printk("Test %s failed.\n", expected);		\
			return false;					\
		}							\
	} while (0)

#define TEST_LL_6_TWO(a, b, c, d, e, f, expected)			\
	do {								\
		u8_t ll1[] = { a, b, c, d, e, f };			\
		u8_t ll2[] = { f, e, d, c, b, a };			\
		char out[2 * sizeof("xx:xx:xx:xx:xx:xx") + 1 + 1];	\
		snprintk(out, sizeof(out), "%s ",			\
			 net_sprint_ll_addr(ll1, sizeof(ll1)));		\
		snprintk(out + sizeof("xx:xx:xx:xx:xx:xx"),		\
			 sizeof(out), "%s",				\
			 net_sprint_ll_addr(ll2, sizeof(ll2)));		\
		if (strcmp(out, expected)) {				\
			printk("Test %s failed, got %s\n", expected, out); \
			return false;					\
		}							\
	} while (0)

#define TEST_IPV6(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, expected)  \
	do {								     \
		struct in6_addr addr = { { { a, b, c, d, e, f, g, h,	     \
					       i, j, k, l, m, n, o, p } } }; \
		char *ptr = net_sprint_ipv6_addr(&addr);		     \
		if (strcmp(ptr, expected)) {				     \
			printk("Test %s failed, got %s\n", expected, ptr);   \
			return false;					     \
		}							     \
	} while (0)

#define TEST_IPV4(a, b, c, d, expected)					\
	do {								\
		struct in_addr addr = { { { a, b, c, d } } };		\
		char *ptr = net_sprint_ipv4_addr(&addr);		\
		if (strcmp(ptr, expected)) {				\
			printk("Test %s failed, got %s\n", expected, ptr); \
			return false;					\
		}							\
	} while (0)

struct net_test_context {
	u8_t mac_addr[6];
	struct net_linkaddr ll_addr;
};

int net_test_init(struct device *dev)
{
	struct net_test_context *net_test_context = dev->driver_data;

	net_test_context = net_test_context;

	return 0;
}

static u8_t *net_test_get_mac(struct device *dev)
{
	struct net_test_context *context = dev->driver_data;

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

	return context->mac_addr;
}

static void net_test_iface_init(struct net_if *iface)
{
	u8_t *mac = net_test_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);
}

static int tester_send(struct net_if *iface, struct net_pkt *pkt)
{
	net_pkt_unref(pkt);
	return 0;
}

struct net_test_context net_test_context_data;

static struct net_if_api net_test_if_api = {
	.init = net_test_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_addr_test, "net_addr_test",
		net_test_init, &net_test_context_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		&net_test_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);

static bool run_tests(void)
{
	struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
	struct in6_addr any = IN6ADDR_ANY_INIT;
	struct in6_addr mcast = { { { 0xff, 0x84, 0, 0, 0, 0, 0, 0,
				      0, 0, 0, 0, 0, 0, 0, 0x2 } } };
	struct in6_addr addr6 = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0,
				      0, 0, 0, 0, 0, 0, 0, 0x1 } } };
	struct in6_addr addr6_pref1 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					    0, 0, 0, 0, 0, 0, 0, 0x1 } } };
	struct in6_addr addr6_pref2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					    0, 0, 0, 0, 0, 0, 0, 0x2 } } };
	struct in6_addr addr6_pref3 = { { { 0x20, 0x01, 0x0d, 0xb8, 0x64, 0, 0,
					    0, 0, 0, 0, 0, 0, 0, 0, 0x2 } } };
	struct in6_addr *tmp;
	const struct in6_addr *out;
	struct net_if_addr *ifaddr1, *ifaddr2;
	struct net_if_mcast_addr *ifmaddr1;
	struct in_addr addr4 = { { { 192, 168, 0, 1 } } };
	struct in_addr match_addr = { { { 192, 168, 0, 2 } } };
	struct in_addr fail_addr = { { { 10, 1, 0, 2 } } };
	struct in_addr netmask = { { { 255, 255, 255, 0 } } };
	struct in_addr gw = { { { 192, 168, 0, 42 } } };
	struct in_addr loopback4 = { { { 127, 0, 0, 1 } } };
	struct net_if *iface;
	int i;

	TEST_BYTE_1(0xde, "DE");
	TEST_BYTE_1(0x09, "09");
	TEST_BYTE_2(0xa9, "a9");
	TEST_BYTE_2(0x80, "80");

	TEST_LL_6(0x12, 0x9f, 0xe3, 0x01, 0x7f, 0x00, "12:9F:E3:01:7F:00");
	TEST_LL_8(0x12, 0x9f, 0xe3, 0x01, 0x7f, 0x00, 0xff, 0x0f, \
		  "12:9F:E3:01:7F:00:FF:0F");

	TEST_LL_6_TWO(0x12, 0x9f, 0xe3, 0x01, 0x7f, 0x00,	\
		      "12:9F:E3:01:7F:00 00:7F:01:E3:9F:12");

	TEST_IPV6(0x20, 1, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \
		  "2001:db8::1");

	TEST_IPV6(0x20, 0x01, 0x0d, 0xb8, 0x12, 0x34, 0x56, 0x78,	\
		  0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x02, 0x03, 0x04,	\
		  "2001:db8:1234:5678:9abc:def0:102:304");

	TEST_IPV6(0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
		  0x0c, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,	\
		  "fe80::cb8:0:0:2");

	TEST_IPV6(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,	\
		  "::1");

	TEST_IPV6(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
		  "::");

	TEST_IPV4(192, 168, 0, 1, "192.168.0.1");
	TEST_IPV4(0, 0, 0, 0, "0.0.0.0");
	TEST_IPV4(127, 0, 0, 1, "127.0.0.1");

	printk("IP address print tests passed\n");

	if (!net_is_ipv6_addr_loopback(&loopback)) {
		printk("IPv6 loopback address check failed.\n");
		return false;
	}

	if (!net_is_ipv6_addr_mcast(&mcast)) {
		printk("IPv6 multicast address check failed.\n");
		return false;
	}

	ifaddr1 = net_if_ipv6_addr_add(net_if_get_default(),
				      &addr6,
				      NET_ADDR_MANUAL,
				      0);
	if (!ifaddr1) {
		printk("IPv6 interface address add failed\n");
		return false;
	}

	ifaddr2 = net_if_ipv6_addr_lookup(&addr6, NULL);
	if (ifaddr1 != ifaddr2) {
		printk("IPv6 interface address mismatch\n");
		return false;
	}

	if (net_is_my_ipv6_addr(&loopback)) {
		printk("My IPv6 loopback address check failed\n");
		return false;
	}

	if (!net_is_my_ipv6_addr(&addr6)) {
		printk("My IPv6 address check failed\n");
		return false;
	}

	if (!net_is_ipv6_prefix((u8_t *)&addr6_pref1,
				(u8_t *)&addr6_pref2,
				64)) {
		printk("Same IPv6 prefix test failed\n");
		return false;
	}

	if (net_is_ipv6_prefix((u8_t *)&addr6_pref1,
			       (u8_t *)&addr6_pref3,
			       64)) {
		printk("Different IPv6 prefix test failed\n");
		return false;
	}

	if (net_is_ipv6_prefix((u8_t *)&addr6_pref1,
			       (u8_t *)&addr6_pref2,
			       128)) {
		printk("Different full IPv6 prefix test failed\n");
		return false;
	}

	if (net_is_ipv6_prefix((u8_t *)&addr6_pref1,
			       (u8_t *)&addr6_pref3,
			       255)) {
		printk("Too long prefix test failed\n");
		return false;
	}

	ifmaddr1 = net_if_ipv6_maddr_add(net_if_get_default(), &mcast);
	if (!ifmaddr1) {
		printk("IPv6 multicast address add failed\n");
		return false;
	}

	ifmaddr1 = net_if_ipv6_maddr_add(net_if_get_default(), &addr6);
	if (ifmaddr1) {
		printk("IPv6 multicast address could be added failed\n");
		return false;
	}

	ifaddr1 = net_if_ipv4_addr_add(net_if_get_default(),
				      &addr4,
				      NET_ADDR_MANUAL,
				      0);
	if (!ifaddr1) {
		printk("IPv4 interface address add failed\n");
		return false;
	}

	if (!net_is_my_ipv4_addr(&addr4)) {
		printk("My IPv4 address check failed\n");
		return false;
	}

	if (net_is_my_ipv4_addr(&loopback4)) {
		printk("My IPv4 loopback address check failed\n");
		return false;
	}

	if (memcmp(net_ipv6_unspecified_address(), &any, sizeof(any))) {
		printk("My IPv6 unspecified address check failed\n");
		return false;
	}

	ifaddr2 = net_if_ipv6_addr_add(net_if_get_default(),
				       &addr6,
				       NET_ADDR_AUTOCONF,
				       0);
	if (!ifaddr2) {
		printk("IPv6 ll address autoconf add failed\n");
		return false;
	}
	ifaddr2->addr_state = NET_ADDR_PREFERRED;

	tmp = net_if_ipv6_get_ll(net_if_get_default(), NET_ADDR_PREFERRED);
	if (memcmp(tmp, &addr6.s6_addr, sizeof(struct in6_addr))) {
		printk("IPv6 ll address fetch failed\n");
		return false;
	}

	ifaddr2->addr_state = NET_ADDR_DEPRECATED;

	tmp = net_if_ipv6_get_ll(net_if_get_default(), NET_ADDR_PREFERRED);
	if (tmp || !memcmp(tmp, &any, sizeof(struct in6_addr))) {
		printk("IPv6 preferred ll address fetch failed\n");
		return false;
	}

	ifaddr1 = net_if_ipv6_addr_add(net_if_get_default(),
				       &addr6_pref2,
				       NET_ADDR_AUTOCONF,
				       0);
	if (!ifaddr1) {
		printk("IPv6 global address autoconf add failed\n");
		return false;
	}
	ifaddr1->addr_state = NET_ADDR_PREFERRED;

	/* Two tests, first with interface given, then when iface is NULL */
	for (i = 0, iface = net_if_get_default(); i < 2; i++, iface = NULL) {
		ifaddr2->addr_state = NET_ADDR_DEPRECATED;

		out = net_if_ipv6_select_src_addr(iface, &addr6_pref1);
		if (!out) {
			printk("IPv6 src addr selection failed, iface %p\n",
				iface);
			return false;
		}
		printk("Selected IPv6 address %s, iface %p\n",
		       net_sprint_ipv6_addr(out), iface);

		if (memcmp(out->s6_addr, &addr6_pref2.s6_addr,
			   sizeof(struct in6_addr))) {
			printk("IPv6 wrong src address selected, iface %p\n",
			       iface);
			return false;
		}

		/* Now we should get :: address */
		out = net_if_ipv6_select_src_addr(iface, &addr6);
		if (!out) {
			printk("IPv6 src any addr selection failed, "
			       "iface %p\n", iface);
			return false;
		}
		printk("Selected IPv6 address %s, iface %p\n",
		       net_sprint_ipv6_addr(out), iface);

		if (memcmp(out->s6_addr, &any.s6_addr,
			   sizeof(struct in6_addr))) {
			printk("IPv6 wrong src any address selected, "
			       "iface %p\n", iface);
			return false;
		}

		ifaddr2->addr_state = NET_ADDR_PREFERRED;

		/* Now we should get ll address */
		out = net_if_ipv6_select_src_addr(iface, &addr6);
		if (!out) {
			printk("IPv6 src ll addr selection failed, iface %p\n",
				iface);
			return false;
		}
		printk("Selected IPv6 address %s, iface %p\n",
		       net_sprint_ipv6_addr(out), iface);

		if (memcmp(out->s6_addr, &addr6.s6_addr,
			   sizeof(struct in6_addr))) {
			printk("IPv6 wrong src ll address selected, "
			       "iface %p\n", iface);
			return false;
		}
	}

	iface = net_if_get_default();

	net_if_ipv4_set_gw(iface, &gw);
	net_if_ipv4_set_netmask(iface, &netmask);

	if (net_ipv4_addr_mask_cmp(iface, &fail_addr)) {
		printk("IPv4 wrong match failed\n");
		return false;
	}

	if (!net_ipv4_addr_mask_cmp(iface, &match_addr)) {
		printk("IPv4 match failed\n");
		return false;
	}

	printk("IP address checks passed\n");

	return true;
}

void main(void)
{
	k_thread_priority_set(k_current_get(), K_PRIO_COOP(7));

	if (run_tests()) {
		TC_END_REPORT(TC_PASS);
	} else {
		TC_END_REPORT(TC_FAIL);
	}
}
