/*
 * Copyright (c) 2019 Laird Connectivity
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr/types.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <misc/printk.h>

#include <ztest.h>

#include <net/ethernet.h>
#include <net/dummy.h>
#include <net/buf.h>
#include <net/net_ip.h>
#include <net/net_if.h>
#include <net/dns_resolve.h>
#include <net/net_event.h>
#include <net/net_mgmt.h>

#define NET_LOG_ENABLED 1
#include "net_private.h"

#if defined(CONFIG_DNS_RESOLVER_LOG_LEVEL_DBG)
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif

#define NAME4 "4.zephyr.test"
#define NAME6 "6.zephyr.test"
#define NAME_IPV4 "192.0.2.1"
#define NAME_IPV6 "2001:db8::1"

#define DNS_NAME_IPV4 "192.0.2.4"
#define DNS_NAME_IPV6 "2001:db8::4"

#define DNS_TIMEOUT 500 /* ms */

#if defined(CONFIG_NET_IPV6)
/* 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 } } };
#endif

#if defined(CONFIG_NET_IPV4)
/* Interface 1 addresses */
static struct in_addr my_addr2 = { { { 192, 0, 2, 1 } } };
#endif

static struct net_mgmt_event_callback mgmt_cb;
static struct k_sem dns_added;
static struct k_sem dns_removed;

static struct net_if *iface1;

#if defined(CONFIG_NET_IPV4)
static struct dns_resolve_context resv_ipv4;
static struct dns_resolve_context resv_ipv4_2;
#endif
#if defined(CONFIG_NET_IPV6)
static struct dns_resolve_context resv_ipv6;
static struct dns_resolve_context resv_ipv6_2;
#endif

/* this must be higher that the DNS_TIMEOUT */
#define WAIT_TIME ((DNS_TIMEOUT + 300) * 3)

struct net_if_test {
	u8_t idx;
	u8_t mac_addr[sizeof(struct net_eth_addr)];
};

static int net_iface_dev_init(struct device *dev)
{
	return 0;
}

static u8_t *net_iface_get_mac(struct device *dev)
{
	struct net_if_test *data = dev->driver_data;

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

	return data->mac_addr;
}

static void net_iface_init(struct net_if *iface)
{
	u8_t *mac = net_iface_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
			     NET_LINK_ETHERNET);
}

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

	return 0;
}

struct net_if_test net_iface1_data;

static struct dummy_api net_iface_api = {
	.iface_api.init = net_iface_init,
	.send = sender_iface,
};

#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)

NET_DEVICE_INIT_INSTANCE(net_iface1_test,
			 "iface1",
			 iface1,
			 net_iface_dev_init,
			 &net_iface1_data,
			 NULL,
			 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
			 &net_iface_api,
			 _ETH_L2_LAYER,
			 _ETH_L2_CTX_TYPE,
			 127);

static void dns_evt_handler(struct net_mgmt_event_callback *cb,
			      u32_t mgmt_event, struct net_if *iface)
{
	if (mgmt_event == NET_EVENT_DNS_SERVER_ADD) {
		k_sem_give(&dns_added);
	} else if (mgmt_event == NET_EVENT_DNS_SERVER_DEL) {
		k_sem_give(&dns_removed);
	}
}

static void test_init(void)
{
	struct net_if_addr *ifaddr;

	iface1 = net_if_get_by_index(0);
	zassert_is_null(iface1, "iface1");

	iface1 = net_if_get_by_index(1);

	((struct net_if_test *)net_if_get_device(iface1)->driver_data)->idx =
		net_if_get_by_iface(iface1);

#if defined(CONFIG_NET_IPV6)
	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");

		return;
	}

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

#if defined(CONFIG_NET_IPV4)
	ifaddr = net_if_ipv4_addr_add(iface1, &my_addr2,
				      NET_ADDR_MANUAL, 0);
	if (!ifaddr) {
		DBG("Cannot add IPv4 address %s\n",
		       net_sprint_ipv4_addr(&my_addr2));
		zassert_not_null(ifaddr, "addr2");

		return;
	}

	ifaddr->addr_state = NET_ADDR_PREFERRED;
#endif

	net_if_up(iface1);

	k_sem_init(&dns_added, 0, 1);
	k_sem_init(&dns_removed, 0, 1);

	net_mgmt_init_event_callback(&mgmt_cb, dns_evt_handler,
				     NET_EVENT_DNS_SERVER_ADD |
				     NET_EVENT_DNS_SERVER_DEL);
	net_mgmt_add_event_callback(&mgmt_cb);
}

static void dns_do_not_add_add_callback6(void)
{
#if defined(CONFIG_NET_IPV6)
	/* Wait for DNS added callback without adding DNS */

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS added callback when should not have");
	}
#endif
}

/* Wait for DNS added callback after adding DNS */
static void dns_add_callback6(void)
{
#if defined(CONFIG_NET_IPV6)

	struct dns_resolve_context *dnsCtx = &resv_ipv6;
	const char *dns_servers_str[] = { DNS_NAME_IPV6, NULL };
	int ret;

	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}
#endif
}

static void dns_remove_callback6(void)
{
#if defined(CONFIG_NET_IPV6)
	/* Wait for DNS removed callback after removing DNS */

	int ret;

	ret = dns_resolve_close(&resv_ipv6);

	zassert_equal(ret, 0, "Cannot remove DNS server");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS removed callback");
	}
#endif
}

static void dns_remove_none_callback6(void)
{
#if defined(CONFIG_NET_IPV6)
	/* Wait for DNS removed callback without removing DNS */
	int ret;

	ret = dns_resolve_close(&resv_ipv6);

	zassert_not_equal(ret, 0, "Cannot remove DNS server");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS removed callback when should not have");
	}
#endif
}

static void dns_add_remove_two_callback6(void)
{
#if defined(CONFIG_NET_IPV6)
	struct dns_resolve_context *dnsCtx = &resv_ipv6;
	const char *dns_servers_str[] = { DNS_NAME_IPV6, NULL };
	int ret;

	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}

	/* Add second DNS entry */
	dnsCtx = &resv_ipv6_2;
	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}

	/* Check both DNS servers are used */
	zassert_true(resv_ipv6.is_used, "DNS server #1 is missing");
	zassert_true(resv_ipv6_2.is_used, "DNS server #2 is missing");

	/* Remove first DNS server */
	dnsCtx = &resv_ipv6;
	ret = dns_resolve_close(dnsCtx);
	zassert_equal(ret, 0, "Cannot remove DNS server #1");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS removed callback when should not have");
	}

	/* Check second DNS servers is used */
	zassert_false(resv_ipv6.is_used, "DNS server #1 is active");
	zassert_true(resv_ipv6_2.is_used, "DNS server #2 is missing");

	/* Check first DNS server cannot be removed once removed */
	ret = dns_resolve_close(dnsCtx);
	zassert_not_equal(ret, 0,
			  "Successful result code when attempting to "
			  "remove DNS server #1 again");

	/* Remove second DNS server */
	dnsCtx = &resv_ipv6_2;
	ret = dns_resolve_close(dnsCtx);
	zassert_equal(ret, 0, "Cannot remove DNS server #2");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			     "Received DNS removed callback when should "
			     "not have");
	}

	/* Check neither DNS server is used */
	zassert_false(resv_ipv6.is_used, "DNS server #1 isa ctive");
	zassert_false(resv_ipv6_2.is_used, "DNS server #2 is active");

	/* Check first DNS server cannot be removed once removed */
	ret = dns_resolve_close(dnsCtx);
	zassert_not_equal(ret, 0,
			  "Successful result code when attempting "
			  "to remove DNS server #1 again");
#endif
}

static void dns_do_not_add_add_callback(void)
{
#if defined(CONFIG_NET_IPV4)
	/* Wait for DNS added callback without adding DNS */

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS added callback when should not have");
	}
#endif
}

static void dns_add_callback(void)
{
#if defined(CONFIG_NET_IPV4)
	/* Wait for DNS added callback after adding DNS */
	struct dns_resolve_context *dnsCtx = &resv_ipv4;
	const char *dns_servers_str[] = { DNS_NAME_IPV4, NULL };
	int ret;

	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}
#endif
}

static void dns_remove_callback(void)
{
#if defined(CONFIG_NET_IPV4)
	/* Wait for DNS removed callback after removing DNS */
	int ret;

	ret = dns_resolve_close(&resv_ipv4);

	zassert_equal(ret, 0, "Cannot remove DNS server");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS removed callback");
	}
#endif
}

static void dns_remove_none_callback(void)
{
#if defined(CONFIG_NET_IPV4)
	/* Wait for DNS removed callback without removing DNS */
	int ret;

	ret = dns_resolve_close(&resv_ipv4);

	zassert_not_equal(ret, 0, "Cannot remove DNS server");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS removed callback when should not have");
	}
#endif
}

static void dns_add_remove_two_callback(void)
{
#if defined(CONFIG_NET_IPV4)
	struct dns_resolve_context *dnsCtx = &resv_ipv4;
	const char *dns_servers_str[] = { DNS_NAME_IPV4, NULL };
	int ret;

	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}

	/* Add second DNS entry */
	dnsCtx = &resv_ipv4_2;
	dns_resolve_close(dnsCtx);

	ret = dns_resolve_init(dnsCtx, dns_servers_str, NULL);
	if (ret < 0) {
		LOG_ERR("dns_resolve_init fail (%d)", ret);
		return;
	}

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_added, WAIT_TIME)) {
		zassert_true(false,
			     "Timeout while waiting for DNS added callback");
	}

	/* Check both DNS servers are used */
	zassert_true(resv_ipv4.is_used, "DNS server #1 is missing");
	zassert_true(resv_ipv4_2.is_used, "DNS server #2 is missing");

	/* Remove first DNS server */
	dnsCtx = &resv_ipv4;
	ret = dns_resolve_close(dnsCtx);
	zassert_equal(ret, 0, "Cannot remove DNS server #1");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			"Received DNS removed callback when should not have");
	}

	/* Check second DNS servers is used */
	zassert_false(resv_ipv4.is_used, "DNS server #1 is active");
	zassert_true(resv_ipv4_2.is_used, "DNS server #2 is missing");

	/* Check first DNS server cannot be removed once removed */
	ret = dns_resolve_close(dnsCtx);
	zassert_not_equal(ret, 0,
			  "Successful result code when attempting to "
			  "remove DNS server #1 again");

	/* Remove second DNS server */
	dnsCtx = &resv_ipv4_2;
	ret = dns_resolve_close(dnsCtx);
	zassert_equal(ret, 0, "Cannot remove DNS server #2");

	k_yield(); /* mandatory so that net_if send func gets to run */

	if (k_sem_take(&dns_removed, WAIT_TIME)) {
		zassert_true(true,
			     "Received DNS removed callback when should "
			     "not have");
	}

	/* Check neither DNS server is used */
	zassert_false(resv_ipv4.is_used, "DNS server #1 isa ctive");
	zassert_false(resv_ipv4_2.is_used, "DNS server #2 is active");

	/* Check first DNS server cannot be removed once removed */
	ret = dns_resolve_close(dnsCtx);
	zassert_not_equal(ret, 0,
			  "Successful result code when attempting to "
			  "remove DNS server #1 again");
#endif
}

void test_main(void)
{
	ztest_test_suite(dns_tests,
			 ztest_unit_test(test_init),
			 ztest_unit_test(dns_do_not_add_add_callback6),
			 ztest_unit_test(dns_add_callback6),
			 ztest_unit_test(dns_remove_callback6),
			 ztest_unit_test(dns_remove_none_callback6),
			 ztest_unit_test(dns_add_remove_two_callback6),
			 ztest_unit_test(dns_do_not_add_add_callback),
			 ztest_unit_test(dns_add_callback),
			 ztest_unit_test(dns_remove_callback),
			 ztest_unit_test(dns_remove_none_callback),
			 ztest_unit_test(dns_add_remove_two_callback)

);

	ztest_run_test_suite(dns_tests);
}
