/* 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 <zephyr/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 <zephyr/sys/printk.h>
#include <zephyr/linker/sections.h>
#include <zephyr/random/rand32.h>

#include <ztest.h>

#include <zephyr/net/buf.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/dummy.h>
#include <zephyr/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, NULL,
		    &eth_context, NULL, CONFIG_ETH_INIT_PRIORITY, &api_funcs,
		    NET_ETH_MTU);

ETH_NET_DEVICE_INIT(eth_test2, "eth_test2", eth_init, NULL,
		    &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 addresses 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,
	};
	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");

	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);
}
