/* 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 <random/rand32.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;
	uint8_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)
{
	const struct device *dev = net_if_get_device(iface);
	struct eth_context *context = dev->data;

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

	ethernet_init(iface);
}

static int eth_tx(const 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(const 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(uint8_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(const struct device *dev)
{
	struct eth_context *context = dev->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);
}
