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

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

#include <stdio.h>
#include <ztest_assert.h>
#include <sys_clock.h>
#include <net/net_ip.h>
#include <net/socket.h>
#include <net/socket_net_mgmt.h>
#include <net/net_event.h>
#include <net/ethernet_mgmt.h>

#define MAX_BUF_LEN 64
#define STACK_SIZE 1024
#define THREAD_PRIORITY K_PRIO_COOP(8)

static ZTEST_BMEM int fd;
static ZTEST_BMEM struct in6_addr addr_v6;
static ZTEST_DMEM struct in_addr addr_v4 = { { { 192, 0, 2, 3 } } };

#if IS_ENABLED(CONFIG_NET_SOCKETS_LOG_LEVEL_DBG)
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define DBG(fmt, ...)
#endif

static const u8_t mac_addr_init[6] = { 0x01, 0x02, 0x03,
				       0x04,  0x05,  0x06 };

struct eth_fake_context {
	struct net_if *iface;
	u8_t mac_address[6];

	bool auto_negotiation;
	bool full_duplex;
	bool link_10bt;
	bool link_100bt;
	bool promisc_mode;
	struct {
		bool qav_enabled;
		int idle_slope;
		int delta_bandwidth;
	} priority_queues[2];
};

static struct eth_fake_context eth_fake_data;

static void eth_fake_iface_init(struct net_if *iface)
{
	struct device *dev = net_if_get_device(iface);
	struct eth_fake_context *ctx = dev->driver_data;

	ctx->iface = iface;

	net_if_set_link_addr(iface, ctx->mac_address,
			     sizeof(ctx->mac_address),
			     NET_LINK_ETHERNET);

	ethernet_init(iface);
}

static int eth_fake_send(struct device *dev,
			 struct net_pkt *pkt)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(pkt);

	return 0;
}

static int eth_fake_get_total_bandwidth(struct eth_fake_context *ctx)
{
	if (ctx->link_100bt) {
		return 100 * 1000 * 1000 / 8;
	}

	if (ctx->link_10bt) {
		return 10 * 1000 * 1000 / 8;
	}

	/* No link */
	return 0;
}

static void eth_fake_recalc_qav_delta_bandwidth(struct eth_fake_context *ctx)
{
	int bw;
	int i;

	bw = eth_fake_get_total_bandwidth(ctx);

	for (i = 0; i < ARRAY_SIZE(ctx->priority_queues); ++i) {
		if (bw == 0) {
			ctx->priority_queues[i].delta_bandwidth = 0;
		} else {
			ctx->priority_queues[i].delta_bandwidth =
				(ctx->priority_queues[i].idle_slope * 100);

			ctx->priority_queues[i].delta_bandwidth /= bw;
		}
	}
}

static void eth_fake_recalc_qav_idle_slopes(struct eth_fake_context *ctx)
{
	int bw;
	int i;

	bw = eth_fake_get_total_bandwidth(ctx);

	for (i = 0; i < ARRAY_SIZE(ctx->priority_queues); ++i) {
		ctx->priority_queues[i].idle_slope =
			(ctx->priority_queues[i].delta_bandwidth * bw) / 100;
	}
}

static int eth_fake_set_config(struct device *dev,
			       enum ethernet_config_type type,
			       const struct ethernet_config *config)
{
	struct eth_fake_context *ctx = dev->driver_data;
	int priority_queues_num = ARRAY_SIZE(ctx->priority_queues);
	enum ethernet_qav_param_type qav_param_type;
	int queue_id;

	switch (type) {
	case ETHERNET_CONFIG_TYPE_QAV_PARAM:
		queue_id = config->qav_param.queue_id;
		qav_param_type = config->qav_param.type;

		if (queue_id < 0 || queue_id >= priority_queues_num) {
			return -EINVAL;
		}

		switch (qav_param_type) {
		case ETHERNET_QAV_PARAM_TYPE_STATUS:
			ctx->priority_queues[queue_id].qav_enabled =
				config->qav_param.enabled;
			break;
		case ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE:
			ctx->priority_queues[queue_id].idle_slope =
				config->qav_param.idle_slope;

			eth_fake_recalc_qav_delta_bandwidth(ctx);
			break;
		case ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH:
			ctx->priority_queues[queue_id].delta_bandwidth =
				config->qav_param.delta_bandwidth;

			eth_fake_recalc_qav_idle_slopes(ctx);
			break;
		default:
			return -ENOTSUP;
		}

		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int eth_fake_get_config(struct device *dev,
			       enum ethernet_config_type type,
			       struct ethernet_config *config)
{
	struct eth_fake_context *ctx = dev->driver_data;
	int priority_queues_num = ARRAY_SIZE(ctx->priority_queues);
	enum ethernet_qav_param_type qav_param_type;
	int queue_id;

	switch (type) {
	case ETHERNET_CONFIG_TYPE_QAV_PARAM:
		queue_id = config->qav_param.queue_id;
		qav_param_type = config->qav_param.type;

		if (queue_id < 0 || queue_id >= priority_queues_num) {
			return -EINVAL;
		}

		switch (qav_param_type) {
		case ETHERNET_QAV_PARAM_TYPE_STATUS:
			config->qav_param.enabled =
				ctx->priority_queues[queue_id].qav_enabled;
			break;
		case ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE:
		case ETHERNET_QAV_PARAM_TYPE_OPER_IDLE_SLOPE:
			/* No distinction between idle slopes for fake eth */
			config->qav_param.idle_slope =
				ctx->priority_queues[queue_id].idle_slope;
			break;
		case ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH:
			config->qav_param.delta_bandwidth =
				ctx->priority_queues[queue_id].delta_bandwidth;
			break;
		case ETHERNET_QAV_PARAM_TYPE_TRAFFIC_CLASS:
			/* Default TC for BE - it doesn't really matter here */
			config->qav_param.traffic_class =
				net_tx_priority2tc(NET_PRIORITY_BE);
			break;
		default:
			return -ENOTSUP;
		}

		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static enum ethernet_hw_caps eth_fake_get_capabilities(struct device *dev)
{
	return ETHERNET_AUTO_NEGOTIATION_SET | ETHERNET_LINK_10BASE_T |
		ETHERNET_LINK_100BASE_T | ETHERNET_DUPLEX_SET | ETHERNET_QAV |
		ETHERNET_PROMISC_MODE | ETHERNET_PRIORITY_QUEUES;
}

static struct ethernet_api eth_fake_api_funcs = {
	.iface_api.init = eth_fake_iface_init,

	.get_capabilities = eth_fake_get_capabilities,
	.set_config = eth_fake_set_config,
	.get_config = eth_fake_get_config,
	.send = eth_fake_send,
};

static int eth_fake_init(struct device *dev)
{
	struct eth_fake_context *ctx = dev->driver_data;
	int i;

	ctx->auto_negotiation = true;
	ctx->full_duplex = true;
	ctx->link_10bt = true;
	ctx->link_100bt = false;

	memcpy(ctx->mac_address, mac_addr_init, 6);

	/* Initialize priority queues */
	for (i = 0; i < ARRAY_SIZE(ctx->priority_queues); ++i) {
		ctx->priority_queues[i].qav_enabled = true;
		if (i + 1 == ARRAY_SIZE(ctx->priority_queues)) {
			/* 75% for the last priority queue */
			ctx->priority_queues[i].delta_bandwidth = 75;
		} else {
			/* 0% for the rest */
			ctx->priority_queues[i].delta_bandwidth = 0;
		}
	}

	eth_fake_recalc_qav_idle_slopes(ctx);

	return 0;
}

ETH_NET_DEVICE_INIT(eth_fake, "eth_fake", eth_fake_init, &eth_fake_data,
		    NULL, CONFIG_ETH_INIT_PRIORITY, &eth_fake_api_funcs,
		    NET_ETH_MTU);

/* A test thread that spits out events that we can catch and show to user */
static void trigger_events(void)
{
	int operation = 0;
	struct net_if_addr *ifaddr_v6, *ifaddr_v4;
	struct net_if *iface;
	int ret;

	iface = net_if_get_default();

	net_ipv6_addr_create(&addr_v6, 0x2001, 0x0db8, 0, 0, 0, 0, 0, 0x0003);

	while (1) {
		switch (operation) {
		case 0:
			ifaddr_v6 = net_if_ipv6_addr_add(iface, &addr_v6,
							 NET_ADDR_MANUAL, 0);
			if (!ifaddr_v6) {
				LOG_ERR("Cannot add IPv%c address", '6');
				break;
			}

			break;
		case 1:
			ifaddr_v4 = net_if_ipv4_addr_add(iface, &addr_v4,
							 NET_ADDR_MANUAL, 0);
			if (!ifaddr_v4) {
				LOG_ERR("Cannot add IPv%c address", '4');
				break;
			}

			break;
		case 2:
			ret = net_if_ipv6_addr_rm(iface, &addr_v6);
			if (!ret) {
				LOG_ERR("Cannot del IPv%c address", '6');
				break;
			}

			break;
		case 3:
			ret = net_if_ipv4_addr_rm(iface, &addr_v4);
			if (!ret) {
				LOG_ERR("Cannot del IPv%c address", '4');
				break;
			}

			break;
		default:
			operation = -1;
			break;
		}

		operation++;

		k_sleep(K_MSEC(100));
	}
}

K_THREAD_DEFINE(trigger_events_thread_id, STACK_SIZE,
		trigger_events, NULL, NULL, NULL,
		THREAD_PRIORITY, 0, K_FOREVER);

static char *get_ip_addr(char *ipaddr, size_t len, sa_family_t family,
			 struct net_mgmt_msghdr *hdr)
{
	char *buf;

	buf = net_addr_ntop(family, hdr->nm_msg, ipaddr, len);
	if (!buf) {
		return "?";
	}

	return buf;
}

static void test_net_mgmt_setup(void)
{
	struct sockaddr_nm sockaddr;
	int ret;

	fd = socket(AF_NET_MGMT, SOCK_DGRAM, NET_MGMT_EVENT_PROTO);
	zassert_false(fd < 0, "Cannot create net_mgmt socket (%d)", errno);

	memset(&sockaddr, 0, sizeof(sockaddr));

	sockaddr.nm_family = AF_NET_MGMT;
	sockaddr.nm_ifindex = net_if_get_by_iface(net_if_get_default());
	sockaddr.nm_pid = (uintptr_t)k_current_get();
	sockaddr.nm_mask = NET_EVENT_IPV6_DAD_SUCCEED |
			   NET_EVENT_IPV6_ADDR_ADD |
			   NET_EVENT_IPV6_ADDR_DEL;

	ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
	zassert_false(ret < 0, "Cannot bind net_mgmt socket (%d)", errno);

	k_thread_start(trigger_events_thread_id);
}

static void test_net_mgmt_catch_events(void)
{
	struct sockaddr_nm event_addr;
	socklen_t event_addr_len;
	char ipaddr[INET6_ADDRSTRLEN];
	u8_t buf[MAX_BUF_LEN];
	int event_count = 2;
	int ret;

	while (event_count > 0) {
		struct net_mgmt_msghdr *hdr;

		memset(buf, 0, sizeof(buf));
		event_addr_len = sizeof(event_addr);

		ret = recvfrom(fd, buf, sizeof(buf), 0,
			       (struct sockaddr *)&event_addr,
			       &event_addr_len);
		if (ret < 0) {
			continue;
		}

		hdr = (struct net_mgmt_msghdr *)buf;

		if (hdr->nm_msg_version != NET_MGMT_SOCKET_VERSION_1) {
			/* Do not know how to parse the message */
			continue;
		}

		switch (event_addr.nm_mask) {
		case NET_EVENT_IPV6_ADDR_ADD:
			DBG("IPv6 address added to interface %d (%s)\n",
			    event_addr.nm_ifindex,
			    get_ip_addr(ipaddr, sizeof(ipaddr),
					AF_INET6, hdr));
			zassert_equal(strncmp(ipaddr, "2001:db8::3",
					      sizeof(ipaddr) - 1), 0,
				      "Invalid IPv6 address %s added",
				      ipaddr);
			event_count--;
			break;
		case NET_EVENT_IPV6_ADDR_DEL:
			DBG("IPv6 address removed from interface %d (%s)\n",
			    event_addr.nm_ifindex,
			    get_ip_addr(ipaddr, sizeof(ipaddr),
					AF_INET6, hdr));
			zassert_equal(strncmp(ipaddr, "2001:db8::3",
					      sizeof(ipaddr) - 1), 0,
				      "Invalid IPv6 address %s removed",
				      ipaddr);
			event_count--;
			break;
		}
	}
}

static void test_net_mgmt_catch_kernel(void)
{
	test_net_mgmt_catch_events();
}

static void test_net_mgmt_catch_user(void)
{
	test_net_mgmt_catch_events();
}

static void test_net_mgmt_cleanup(void)
{
	k_thread_abort(trigger_events_thread_id);
}

static void test_ethernet_set_qav(void)
{
	struct ethernet_req_params params;
	int ret;

	memset(&params, 0, sizeof(params));

	params.qav_param.queue_id = 1;
	params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_STATUS;
	params.qav_param.enabled = true;

	ret = setsockopt(fd, SOL_NET_MGMT_RAW,
			 NET_REQUEST_ETHERNET_SET_QAV_PARAM,
			 &params, sizeof(params));
	zassert_equal(ret, 0, "Cannot set Qav parameters");
}

static void test_ethernet_set_qav_kernel(void)
{
	test_ethernet_set_qav();
}

static void test_ethernet_set_qav_user(void)
{
	test_ethernet_set_qav();
}

static void test_ethernet_get_qav(void)
{
	struct ethernet_req_params params;
	socklen_t optlen = sizeof(params);
	int ret;

	memset(&params, 0, sizeof(params));

	params.qav_param.queue_id = 1;
	params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_STATUS;

	ret = getsockopt(fd, SOL_NET_MGMT_RAW,
			 NET_REQUEST_ETHERNET_GET_QAV_PARAM,
			 &params, &optlen);
	zassert_equal(ret, 0, "Cannot get Qav parameters (%d)", ret);
	zassert_equal(optlen, sizeof(params), "Invalid optlen (%d)", optlen);

	zassert_true(params.qav_param.enabled, "Qav not enabled");
}

static void test_ethernet_get_qav_kernel(void)
{
	test_ethernet_get_qav();
}

static void test_ethernet_get_qav_user(void)
{
	test_ethernet_get_qav();
}

static void test_ethernet_get_unknown_option(void)
{
	struct ethernet_req_params params;
	socklen_t optlen = sizeof(params);
	int ret;

	memset(&params, 0, sizeof(params));

	ret = getsockopt(fd, SOL_NET_MGMT_RAW,
			 NET_REQUEST_ETHERNET_GET_PRIORITY_QUEUES_NUM,
			 &params, &optlen);
	zassert_equal(ret, -1, "Could get prio queue parameters (%d)", errno);
	zassert_equal(errno, EINVAL, "prio queue get parameters");
}

static void test_ethernet_get_unknown_opt_kernel(void)
{
	test_ethernet_get_unknown_option();
}

static void test_ethernet_get_unknown_opt_user(void)
{
	test_ethernet_get_unknown_option();
}

static void test_ethernet_set_unknown_option(void)
{
	struct ethernet_req_params params;
	socklen_t optlen = sizeof(params);
	int ret;

	memset(&params, 0, sizeof(params));

	ret = setsockopt(fd, SOL_NET_MGMT_RAW,
			 NET_REQUEST_ETHERNET_SET_MAC_ADDRESS,
			 &params, optlen);
	zassert_equal(ret, -1, "Could set promisc_mode parameters (%d)", errno);
	zassert_equal(errno, EINVAL, "promisc_mode set parameters");
}

static void test_ethernet_set_unknown_opt_kernel(void)
{
	test_ethernet_set_unknown_option();
}

static void test_ethernet_set_unknown_opt_user(void)
{
	test_ethernet_set_unknown_option();
}

void test_main(void)
{
	k_thread_system_pool_assign(k_current_get());

	ztest_test_suite(socket_net_mgmt,
			 ztest_unit_test(test_net_mgmt_setup),
			 ztest_unit_test(test_net_mgmt_catch_kernel),
			 ztest_user_unit_test(test_net_mgmt_catch_user),
			 ztest_unit_test(test_net_mgmt_cleanup),
			 ztest_unit_test(test_ethernet_set_qav_kernel),
			 ztest_user_unit_test(test_ethernet_set_qav_user),
			 ztest_unit_test(test_ethernet_get_qav_kernel),
			 ztest_user_unit_test(test_ethernet_get_qav_user),
			 ztest_unit_test(test_ethernet_get_unknown_opt_kernel),
			 ztest_user_unit_test(
				 test_ethernet_get_unknown_opt_user),
			 ztest_unit_test(test_ethernet_set_unknown_opt_kernel),
			 ztest_user_unit_test(
				 test_ethernet_set_unknown_opt_user));

	ztest_run_test_suite(socket_net_mgmt);
}
