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

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

#include <stdint.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/nbuf.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 {								\
		uint8_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 {								\
		uint8_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 {								\
		uint8_t ll1[] = { a, b, c, d, e, f };			\
		uint8_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 {
	uint8_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 uint8_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)
{
	uint8_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_buf *buf)
{
	net_nbuf_unref(buf);
	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((uint8_t *)&addr6_pref1,
				(uint8_t *)&addr6_pref2,
				64)) {
		printk("Same IPv6 prefix test failed\n");
		return false;
	}

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

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

	if (net_is_ipv6_prefix((uint8_t *)&addr6_pref1,
			       (uint8_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_thread(void)
{
	if (run_tests()) {
		TC_END_REPORT(TC_PASS);
	} else {
		TC_END_REPORT(TC_FAIL);
	}
}

#define STACKSIZE 2000
char __noinit __stack thread_stack[STACKSIZE];

void main(void)
{
	k_thread_spawn(&thread_stack[0], STACKSIZE,
		       (k_thread_entry_t)main_thread, NULL, NULL, NULL,
		       K_PRIO_COOP(7), 0, 0);
}
