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

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

#define NET_LOG_LEVEL CONFIG_NET_L2_ETHERNET_LOG_LEVEL

#include <logging/log.h>
LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);

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

#include <ztest.h>

#include <net/buf.h>
#include <net/net_ip.h>
#include <net/net_pkt.h>
#include <net/ethernet.h>
#include <net/dummy.h>
#include <net/net_l2.h>

#include "ipv6.h"

#define NET_LOG_ENABLED 1
#include "net_private.h"

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif

#define TEST_PORT 9999

static char *test_data = "Test data to be sent";

/* Interface 1 addresses */
static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };

/* Interface 2 addresses */
static struct in6_addr my_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };

/* Destination address for test packets */
static struct in6_addr dst_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 9, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0x1 } } };

/* Extra address is assigned to ll_addr */
static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
				       0, 0, 0, 0xf2, 0xaa, 0x29, 0x02,
				       0x04 } } };

/* Keep track of all ethernet interfaces */
static struct net_if *eth_interfaces[2];

static struct net_context *udp_v6_ctx;

static bool test_failed;
static bool test_started;
static bool do_timestamp;
static bool timestamp_cb_called;
static struct net_if_timestamp_cb timestamp_cb;
static struct net_if_timestamp_cb timestamp_cb_2;
static struct net_if_timestamp_cb timestamp_cb_3;

static K_SEM_DEFINE(wait_data, 0, UINT_MAX);

#define WAIT_TIME K_SECONDS(1)

struct eth_context {
	struct net_if *iface;
	u8_t mac_addr[6];
};

static struct eth_context eth_context;
static struct eth_context eth_context2;

static void eth_iface_init(struct net_if *iface)
{
	struct device *dev = net_if_get_device(iface);
	struct eth_context *context = dev->driver_data;

	net_if_set_link_addr(iface, context->mac_addr,
			     sizeof(context->mac_addr),
			     NET_LINK_ETHERNET);

	ethernet_init(iface);
}

static int eth_tx(struct device *dev, struct net_pkt *pkt)
{
	if (!pkt->buffer) {
		DBG("No data to send!\n");
		return -ENODATA;
	}

	if (test_started) {
		if (do_timestamp) {
			/* Simulate the clock advancing */
			pkt->timestamp.nanosecond = pkt->timestamp.second + 1;

			net_if_add_tx_timestamp(pkt);
		} else {
			k_sem_give(&wait_data);
		}
	}

	test_started = false;

	return 0;
}

static enum ethernet_hw_caps eth_get_capabilities(struct device *dev)
{
	return 0;
}

static struct ethernet_api api_funcs = {
	.iface_api.init = eth_iface_init,

	.get_capabilities = eth_get_capabilities,
	.send = eth_tx,
};

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

static int eth_init(struct device *dev)
{
	struct eth_context *context = dev->driver_data;

	generate_mac(context->mac_addr);

	return 0;
}

ETH_NET_DEVICE_INIT(eth_test, "eth_test", eth_init, device_pm_control_nop,
		    &eth_context, NULL, CONFIG_ETH_INIT_PRIORITY, &api_funcs,
		    NET_ETH_MTU);

ETH_NET_DEVICE_INIT(eth_test2, "eth_test2", eth_init, device_pm_control_nop,
		    &eth_context2, NULL, CONFIG_ETH_INIT_PRIORITY, &api_funcs,
		    NET_ETH_MTU);

static void timestamp_callback(struct net_pkt *pkt)
{
	timestamp_cb_called = true;

	if (do_timestamp) {
		/* This is very artificial test but make sure that we
		 * have advanced the time a bit.
		 */
		zassert_true(pkt->timestamp.nanosecond > pkt->timestamp.second,
			     "Timestamp not working ok (%d < %d)\n",
			     pkt->timestamp.nanosecond, pkt->timestamp.second);
	}

	/* The pkt was ref'ed in send_some_data()() */
	net_pkt_unref(pkt);

	if (do_timestamp) {
		k_sem_give(&wait_data);
	}
}

static void test_timestamp_setup(void)
{
	struct net_if *iface;
	struct net_pkt *pkt;

	iface = eth_interfaces[0];

	net_if_register_timestamp_cb(&timestamp_cb, NULL, iface,
				     timestamp_callback);

	timestamp_cb_called = false;
	do_timestamp = false;

	pkt = net_pkt_alloc_on_iface(iface, K_FOREVER);

	/* Make sure that the callback function is called */
	net_if_call_timestamp_cb(pkt);

	zassert_true(timestamp_cb_called, "Timestamp callback not called\n");
	zassert_equal(atomic_get(&pkt->atomic_ref), 0, "Pkt %p not released\n");
}

static void timestamp_callback_2(struct net_pkt *pkt)
{
	timestamp_cb_called = true;

	if (do_timestamp) {
		/* This is very artificial test but make sure that we
		 * have advanced the time a bit.
		 */
		zassert_true(pkt->timestamp.nanosecond > pkt->timestamp.second,
			     "Timestamp not working ok (%d < %d)\n",
			     pkt->timestamp.nanosecond, pkt->timestamp.second);
	}

	zassert_equal(eth_interfaces[1], net_pkt_iface(pkt),
		      "Invalid interface");

	/* The pkt was ref'ed in send_some_data()() */
	net_pkt_unref(pkt);

	if (do_timestamp) {
		k_sem_give(&wait_data);
	}
}

static void test_timestamp_setup_2nd_iface(void)
{
	struct net_if *iface;
	struct net_pkt *pkt;

	iface = eth_interfaces[1];

	net_if_register_timestamp_cb(&timestamp_cb_2, NULL, iface,
				     timestamp_callback_2);

	timestamp_cb_called = false;
	do_timestamp = false;

	pkt = net_pkt_alloc_on_iface(iface, K_FOREVER);

	/* Make sure that the callback function is called */
	net_if_call_timestamp_cb(pkt);

	zassert_true(timestamp_cb_called, "Timestamp callback not called\n");
	zassert_equal(atomic_get(&pkt->atomic_ref), 0, "Pkt %p not released\n");
}

static void test_timestamp_setup_all(void)
{
	struct net_pkt *pkt;

	net_if_register_timestamp_cb(&timestamp_cb_3, NULL, NULL,
				     timestamp_callback);

	timestamp_cb_called = false;
	do_timestamp = false;

	pkt = net_pkt_alloc_on_iface(eth_interfaces[0], K_FOREVER);

	/* The callback is called twice because we have two matching callbacks
	 * as the interface is set to NULL when registering cb. So we need to
	 * ref the pkt here because the callback releases pkt.
	 */
	net_pkt_ref(pkt);

	/* Make sure that the callback function is called */
	net_if_call_timestamp_cb(pkt);

	zassert_true(timestamp_cb_called, "Timestamp callback not called\n");
	zassert_equal(atomic_get(&pkt->atomic_ref), 0, "Pkt %p not released\n");

	net_if_unregister_timestamp_cb(&timestamp_cb_3);
}

static void test_timestamp_cleanup(void)
{
	struct net_if *iface;
	struct net_pkt *pkt;

	net_if_unregister_timestamp_cb(&timestamp_cb);

	iface = eth_interfaces[0];

	timestamp_cb_called = false;
	do_timestamp = false;

	pkt = net_pkt_alloc_on_iface(iface, K_FOREVER);

	/* Make sure that the callback function is not called after unregister
	 */
	net_if_call_timestamp_cb(pkt);

	zassert_false(timestamp_cb_called, "Timestamp callback called\n");
	zassert_false(atomic_get(&pkt->atomic_ref) < 1, "Pkt %p released\n");

	net_pkt_unref(pkt);
}

struct user_data {
	int eth_if_count;
	int total_if_count;
};

#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
static const char *iface2str(struct net_if *iface)
{
#ifdef CONFIG_NET_L2_ETHERNET
	if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		return "Ethernet";
	}
#endif

	return "<unknown type>";
}
#endif

static void iface_cb(struct net_if *iface, void *user_data)
{
	struct user_data *ud = user_data;

	DBG("Interface %p (%s) [%d]\n", iface, iface2str(iface),
	    net_if_get_by_iface(iface));

	if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		if (ud->eth_if_count >= ARRAY_SIZE(eth_interfaces)) {
			DBG("Invalid interface %p\n", iface);
			return;
		}

		eth_interfaces[ud->eth_if_count++] = iface;
	}

	/* By default all interfaces are down initially */
	net_if_down(iface);

	ud->total_if_count++;
}

static void test_address_setup(void)
{
	struct net_if_addr *ifaddr;
	struct net_if *iface1, *iface2;

	struct user_data ud = { 0 };

	net_if_foreach(iface_cb, &ud);

	iface1 = eth_interfaces[0];
	iface2 = eth_interfaces[1];

	zassert_not_null(iface1, "Interface 1\n");
	zassert_not_null(iface2, "Interface 2\n");

	ifaddr = net_if_ipv6_addr_add(iface1, &my_addr1,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&my_addr1));
		zassert_not_null(ifaddr, "addr1\n");
	}

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

	ifaddr = net_if_ipv6_addr_add(iface1, &ll_addr,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&ll_addr));
		zassert_not_null(ifaddr, "ll_addr\n");
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	ifaddr = net_if_ipv6_addr_add(iface2, &my_addr2,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv6 address %s\n",
		       net_sprint_ipv6_addr(&my_addr2));
		zassert_not_null(ifaddr, "addr2\n");
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;

	net_if_up(iface1);
	net_if_up(iface2);

	/* The interface might receive data which might fail the checks
	 * in the iface sending function, so we need to reset the failure
	 * flag.
	 */
	test_failed = false;
}

static bool add_neighbor(struct net_if *iface, struct in6_addr *addr)
{
	struct net_linkaddr_storage llstorage;
	struct net_linkaddr lladdr;
	struct net_nbr *nbr;

	llstorage.addr[0] = 0x01;
	llstorage.addr[1] = 0x02;
	llstorage.addr[2] = 0x33;
	llstorage.addr[3] = 0x44;
	llstorage.addr[4] = 0x05;
	llstorage.addr[5] = 0x06;

	lladdr.len = 6U;
	lladdr.addr = llstorage.addr;
	lladdr.type = NET_LINK_ETHERNET;

	nbr = net_ipv6_nbr_add(iface, addr, &lladdr, false,
			       NET_IPV6_NBR_STATE_REACHABLE);
	if (!nbr) {
		DBG("Cannot add dst %s to neighbor cache\n",
		    net_sprint_ipv6_addr(addr));
		return false;
	}

	return true;
}

static void send_some_data(struct net_if *iface)
{
	struct sockaddr_in6 dst_addr6 = {
		.sin6_family = AF_INET6,
		.sin6_port = htons(TEST_PORT),
	};
	struct sockaddr_in6 src_addr6 = {
		.sin6_family = AF_INET6,
		.sin6_port = 0,
	};
	bool timestamp = true;
	int ret;

	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP,
			      &udp_v6_ctx);
	zassert_equal(ret, 0, "Create IPv6 UDP context failed\n");

	memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr));
	memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr));

	ret = net_context_bind(udp_v6_ctx, (struct sockaddr *)&src_addr6,
			       sizeof(struct sockaddr_in6));
	zassert_equal(ret, 0, "Context bind failure test failed\n");

	ret = add_neighbor(iface, &dst_addr);
	zassert_true(ret, "Cannot add neighbor\n");

	net_context_set_option(udp_v6_ctx, NET_OPT_TIMESTAMP,
			       &timestamp, sizeof(timestamp));

	ret = net_context_sendto(udp_v6_ctx, test_data, strlen(test_data),
				 (struct sockaddr *)&dst_addr6,
				 sizeof(struct sockaddr_in6),
				 NULL, K_NO_WAIT, NULL);
	zassert_true(ret > 0, "Send UDP pkt failed\n");

	net_context_unref(udp_v6_ctx);
}

static void test_check_timestamp_before_enabling(void)
{
	test_started = true;
	do_timestamp = false;

	send_some_data(eth_interfaces[0]);

	if (k_sem_take(&wait_data, WAIT_TIME)) {
		DBG("Timeout while waiting interface data\n");
		zassert_false(true, "Timeout\n");
	}
}

static void test_check_timestamp_after_enabling(void)
{
	test_started = true;
	do_timestamp = true;

	send_some_data(eth_interfaces[0]);

	if (k_sem_take(&wait_data, WAIT_TIME)) {
		DBG("Timeout while waiting interface data\n");
		zassert_false(true, "Timeout\n");
	}
}

void test_main(void)
{
	ztest_test_suite(net_tx_timestamp_test,
			 ztest_unit_test(test_address_setup),
			 ztest_unit_test(test_check_timestamp_before_enabling),
			 ztest_unit_test(test_timestamp_setup),
			 ztest_unit_test(test_timestamp_setup_2nd_iface),
			 ztest_unit_test(test_timestamp_setup_all),
			 ztest_unit_test(test_check_timestamp_after_enabling),
			 ztest_unit_test(test_timestamp_cleanup)
			 );

	ztest_run_test_suite(net_tx_timestamp_test);
}
