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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_txtime_sample, LOG_LEVEL_DBG);

#include <zephyr/kernel.h>
#include <errno.h>
#include <stdio.h>
#include <inttypes.h>
#include <zephyr/drivers/ptp_clock.h>
#include <zephyr/shell/shell.h>

#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/net_event.h>
#include <zephyr/net/conn_mgr.h>

#include <zephyr/net/socket.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/ethernet_mgmt.h>

#define APP_BANNER "Run SO_TXTIME client"

#define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | \
		     NET_EVENT_IPV4_DHCP_STOP)
#define EVENT_MASK (NET_EVENT_L4_CONNECTED | \
		    NET_EVENT_L4_DISCONNECTED)

#define STACK_SIZE 2048
#define THREAD_PRIORITY K_PRIO_COOP(8)
#define WAIT_PERIOD (1 * MSEC_PER_SEC)
#define MAX_MSG_LEN 64

static char txtime_str[MAX_MSG_LEN];

static struct k_sem quit_lock;
static struct net_mgmt_event_callback mgmt_cb;
static struct net_mgmt_event_callback dhcpv4_cb;

struct app_data {
	const struct device *clk;
	struct sockaddr peer;
	socklen_t peer_addr_len;
	int sock;
};

static struct app_data data = {
	.sock = -1,
};

static k_tid_t tx_tid;
static K_THREAD_STACK_DEFINE(tx_stack, STACK_SIZE);
static struct k_thread tx_thread;

static k_tid_t rx_tid;
static K_THREAD_STACK_DEFINE(rx_stack, STACK_SIZE);
static struct k_thread rx_thread;

K_SEM_DEFINE(run_app, 0, 1);
static bool want_to_quit;
static bool connected;

extern int init_vlan(void);

static void quit(void)
{
	k_sem_give(&quit_lock);
}

static void event_handler(struct net_mgmt_event_callback *cb,
			  uint32_t mgmt_event, struct net_if *iface)
{
	static bool dhcpv4_done;

	if (want_to_quit) {
		k_sem_give(&run_app);
		want_to_quit = false;
	}

	if (IS_ENABLED(CONFIG_NET_DHCPV4)) {
		if (mgmt_event == NET_EVENT_IPV4_DHCP_BOUND) {
			LOG_INF("DHCPv4 bound");
			dhcpv4_done = true;

			if (connected) {
				k_sem_give(&run_app);
			}

			return;
		}

		if (mgmt_event == NET_EVENT_IPV4_DHCP_STOP) {
			dhcpv4_done = false;
			return;
		}
	}

	if (mgmt_event == NET_EVENT_L4_CONNECTED) {
		if (!connected) {
			LOG_INF("Network connected");
		}

		connected = true;

		/* Go to connected state only after DHCPv4 is done */
		if (!IS_ENABLED(CONFIG_NET_DHCPV4) || dhcpv4_done) {
			k_sem_give(&run_app);
		}

		return;
	}

	if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
		if (connected == false) {
			LOG_INF("Waiting network to be connected");
		} else {
			LOG_INF("Network disconnected");
			connected = false;
		}

		k_sem_reset(&run_app);

		return;
	}
}

static void rx(struct app_data *data)
{
	static uint8_t recv_buf[sizeof(txtime_str)];
	struct sockaddr src;
	socklen_t addr_len = data->peer_addr_len;
	ssize_t len = 0;

	while (true) {
		len += recvfrom(data->sock, recv_buf, sizeof(recv_buf), 0,
				&src, &addr_len);
		if (!(len % (100 * 1024))) {
			LOG_DBG("Received %zd kb data", len / 1024);
		}
	}
}

static void tx(struct app_data *data)
{
	struct net_ptp_time time;
	struct msghdr msg;
	struct cmsghdr *cmsg;
	struct iovec io_vector[1];
	union {
		struct cmsghdr hdr;
		unsigned char  buf[CMSG_SPACE(sizeof(uint64_t))];
	} cmsgbuf;
	uint64_t txtime, delay, interval;
	int ret;
	int print_offset;

	print_offset = IS_ENABLED(CONFIG_NET_SAMPLE_PACKET_SOCKET) ?
		sizeof(struct net_eth_hdr) : 0;

	interval = CONFIG_NET_SAMPLE_PACKET_INTERVAL * NSEC_PER_USEC *
							USEC_PER_MSEC;
	delay = CONFIG_NET_SAMPLE_PACKET_TXTIME * NSEC_PER_USEC;

	io_vector[0].iov_base = (void *)txtime_str;

	memset(&msg, 0, sizeof(msg));
	msg.msg_control = &cmsgbuf.buf;
	msg.msg_controllen = sizeof(cmsgbuf.buf);
	msg.msg_iov = io_vector;
	msg.msg_iovlen = 1;
	msg.msg_name = &data->peer;
	msg.msg_namelen = data->peer_addr_len;

	cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_len = CMSG_LEN(sizeof(txtime));
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_TXTIME;

	LOG_DBG("Sending network packets with SO_TXTIME");

	ptp_clock_get(data->clk, &time);
	txtime = (time.second * NSEC_PER_SEC) + time.nanosecond;

	snprintk(txtime_str + print_offset,
		 sizeof(txtime_str) - print_offset, "%"PRIx64, txtime);
	io_vector[0].iov_len = sizeof(txtime_str);

	while (1) {
		*(uint64_t *)CMSG_DATA(cmsg) = txtime + delay;

		ret = sendmsg(data->sock, &msg, 0);
		if (ret < 0) {
			if (errno != ENOMEM) {
				LOG_DBG("Message send failed (%d)", -errno);
				quit();
				break;
			}
		}

		txtime += interval;
		snprintk(txtime_str + print_offset,
			 sizeof(txtime_str) - print_offset, "%"PRIx64, txtime);

		k_sleep(K_NSEC(interval));
	}
}

static int get_local_ipv6(struct net_if *iface, struct sockaddr *peer,
			  struct sockaddr *local, socklen_t *addrlen)
{
	const struct in6_addr *addr;

	if (peer->sa_family != AF_INET6) {
		return 0;
	}

	addr = net_if_ipv6_select_src_addr(iface, &net_sin6(peer)->sin6_addr);
	if (!addr) {
		LOG_ERR("Cannot get local %s address", "IPv6");
		return -EINVAL;
	}

	memcpy(&net_sin6(local)->sin6_addr, addr, sizeof(*addr));
	local->sa_family = AF_INET6;
	*addrlen = sizeof(struct sockaddr_in6);

	return 0;
}

static int get_local_ipv4(struct net_if *iface, struct sockaddr *peer,
			  struct sockaddr *local, socklen_t *addrlen)
{
	const struct in_addr *addr;

	if (peer->sa_family != AF_INET) {
		return 0;
	}

	addr = net_if_ipv4_select_src_addr(iface, &net_sin(peer)->sin_addr);
	if (!addr) {
		LOG_ERR("Cannot get local %s address", "IPv4");
		return -EINVAL;
	}

	memcpy(&net_sin(local)->sin_addr, addr, sizeof(*addr));
	local->sa_family = AF_INET;
	*addrlen = sizeof(struct sockaddr_in);

	return 0;
}

static int create_socket(struct net_if *iface, struct sockaddr *peer)
{
	struct sockaddr local;
	socklen_t addrlen;
	bool optval;
	uint8_t priority;
	int sock;
	int ret;

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

	if (IS_ENABLED(CONFIG_NET_SAMPLE_PACKET_SOCKET)) {
		struct sockaddr_ll *addr;

		sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
		if (sock < 0) {
			LOG_ERR("Cannot create %s socket (%d)", "packet",
				-errno);
			return -errno;
		}

		addr = (struct sockaddr_ll *)&local;
		addr->sll_ifindex = net_if_get_by_iface(net_if_get_default());
		addr->sll_family = AF_PACKET;
		addrlen = sizeof(struct sockaddr_ll);

		LOG_DBG("Binding to interface %d (%p)", addr->sll_ifindex,
			net_if_get_by_index(addr->sll_ifindex));
	}

	if (IS_ENABLED(CONFIG_NET_SAMPLE_UDP_SOCKET)) {
		char addr_str[INET6_ADDRSTRLEN];

		sock = socket(peer->sa_family, SOCK_DGRAM, IPPROTO_UDP);
		if (sock < 0) {
			LOG_ERR("Cannot create %s socket (%d)", "UDP", -errno);
			return -errno;
		}

		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    peer->sa_family == AF_INET6) {
			ret = get_local_ipv6(iface, peer, &local, &addrlen);
			if (ret < 0) {
				return ret;
			}

			net_addr_ntop(AF_INET6, &net_sin6(&local)->sin6_addr,
				      addr_str, sizeof(addr_str));
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   peer->sa_family == AF_INET) {
			ret = get_local_ipv4(iface, peer, &local, &addrlen);
			if (ret < 0) {
				return ret;
			}

			net_addr_ntop(AF_INET, &net_sin(&local)->sin_addr,
				      addr_str, sizeof(addr_str));
		} else {
			LOG_ERR("Invalid socket family %d", peer->sa_family);
			return -EINVAL;
		}

		LOG_DBG("Binding to %s", addr_str);
	}

	ret = bind(sock, &local, addrlen);
	if (ret < 0) {
		LOG_ERR("Cannot bind socket (%d)", -errno);
		return -errno;
	}

	optval = true;
	ret = setsockopt(sock, SOL_SOCKET, SO_TXTIME, &optval, sizeof(optval));
	if (ret < 0) {
		LOG_ERR("Cannot set SO_TXTIME (%d)", -errno);
		return -errno;
	}

	priority = NET_PRIORITY_CA;
	ret = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &priority,
			 sizeof(priority));
	if (ret < 0) {
		LOG_ERR("Cannot set SO_PRIORITY (%d)", -errno);
		return -errno;
	}

	return sock;
}

static int get_peer_address(struct net_if **iface, char *addr_str,
			    int addr_str_len)
{
	int ret;

	ret = net_ipaddr_parse(CONFIG_NET_SAMPLE_PEER,
			       strlen(CONFIG_NET_SAMPLE_PEER),
			       &data.peer);
	if (!ret) {
		LOG_ERR("Cannot parse '%s'", CONFIG_NET_SAMPLE_PEER);
		return -EINVAL;
	}

	if (net_sin(&data.peer)->sin_port == 0) {
		net_sin(&data.peer)->sin_port = htons(4242);
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
					data.peer.sa_family == AF_INET6) {
		*iface = net_if_ipv6_select_src_iface(
					&net_sin6(&data.peer)->sin6_addr);

		net_addr_ntop(data.peer.sa_family,
			      &net_sin6(&data.peer)->sin6_addr, addr_str,
			      addr_str_len);
		data.peer_addr_len = sizeof(struct sockaddr_in6);

	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
					data.peer.sa_family == AF_INET) {
		*iface = net_if_ipv4_select_src_iface(
					&net_sin(&data.peer)->sin_addr);

		net_addr_ntop(data.peer.sa_family,
			      &net_sin(&data.peer)->sin_addr, addr_str,
			      addr_str_len);
		data.peer_addr_len = sizeof(struct sockaddr_in);
	}

	return 0;
}

static void enable_txtime_for_queues(struct net_if *iface)
{
	struct ethernet_req_params params = { 0 };
	int i;

	params.txtime_param.type = ETHERNET_TXTIME_PARAM_TYPE_ENABLE_QUEUES;
	params.txtime_param.enable_txtime = true;

	for (i = 0; i < NET_TC_TX_COUNT; i++) {
		params.txtime_param.queue_id = i;

		(void)net_mgmt(NET_REQUEST_ETHERNET_SET_TXTIME_PARAM,
			       iface, &params, sizeof(params));
	}
}

static void set_qbv_params(struct net_if *iface)
{
	struct ethernet_req_params params = { 0 };
	int i, ret;
	int ports_count = 1, row;

	/* Assume only one port atm, the amount of ports could be
	 * queried from controller by ETHERNET_CONFIG_TYPE_PORTS_NUM
	 */

	/* Set some defaults */
	LOG_DBG("Setting Qbv parameters to %d port%s", ports_count,
		ports_count > 1 ? "s" : "");

	/* One Qbv setting example:
	 *
	 *    Start time: after 20s of current configuring base time
	 *    Cycle time: 20ms
	 *    Number GCL list: 2
	 *    GCL list 0 cycle time: 10ms
	 *    GCL list 0 'set' gate open: Txq1 (default queue),
	 *                                Txq3 (highest priority queue)
	 *    GCL list 1 cycle time: 10ms
	 *    GCL list 1 'set' gate open: Txq0 (background queue)
	 */

	for (i = 0; i < ports_count; ++i) {
		/* Turn on the gate control to first two gates (just for demo
		 * purposes)
		 */
		for (row = 0; row < 2; row++) {
			memset(&params, 0, sizeof(params));

			params.qbv_param.port_id = i;
			params.qbv_param.type =
				ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST;
			params.qbv_param.gate_control.operation = ETHERNET_SET_GATE_STATE;
			params.qbv_param.gate_control.time_interval = 10000000UL;
			params.qbv_param.gate_control.row = row;

			if (row == 0) {
				params.qbv_param.gate_control.
					gate_status[net_tx_priority2tc(NET_PRIORITY_CA)] = true;
				params.qbv_param.gate_control.
					gate_status[net_tx_priority2tc(NET_PRIORITY_BE)] = true;
			} else if (row == 1) {
				params.qbv_param.gate_control.
					gate_status[net_tx_priority2tc(NET_PRIORITY_BK)] = true;
			}

			ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM,
				       iface, &params,
				       sizeof(struct ethernet_req_params));
			if (ret) {
				LOG_ERR("Could not set %s%s (%d) to port %d",
					"gate control list", "", ret, i);
			}
		}

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

		params.qbv_param.port_id = i;
		params.qbv_param.type =
				ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST_LEN;
		params.qbv_param.gate_control_list_len = MIN(NET_TC_TX_COUNT, 2);

		ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface,
			       &params, sizeof(struct ethernet_req_params));
		if (ret) {
			LOG_ERR("Could not set %s%s (%d) to port %d",
				"gate control list", " len", ret, i);
		}

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

		params.qbv_param.port_id = i;
		params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_TIME;
		params.qbv_param.base_time.second = 20ULL;
		params.qbv_param.base_time.fract_nsecond = 0ULL;
		params.qbv_param.cycle_time.second = 0ULL;
		params.qbv_param.cycle_time.nanosecond = 20000000UL;
		params.qbv_param.extension_time = 0UL;

		ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface,
			       &params, sizeof(struct ethernet_req_params));
		if (ret) {
			LOG_ERR("Could not set %s%s (%d) to port %d",
				"base time", "", ret, i);
		}
	}
}

static int cmd_sample_quit(const struct shell *sh,
			  size_t argc, char *argv[])
{
	want_to_quit = true;

	quit();

	conn_mgr_resend_status();

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sample_commands,
	SHELL_CMD(quit, NULL,
		  "Quit the sample application\n",
		  cmd_sample_quit),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(sample, &sample_commands,
		   "Sample application commands", NULL);

int main(void)
{
	struct net_if *iface = NULL;
	char addr_str[INET6_ADDRSTRLEN];
	enum ethernet_hw_caps caps;
	int ret, if_index;

	LOG_INF(APP_BANNER);

	k_sem_init(&quit_lock, 0, UINT_MAX);

	if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) {
		net_mgmt_init_event_callback(&mgmt_cb,
					     event_handler, EVENT_MASK);
		net_mgmt_add_event_callback(&mgmt_cb);

		if (IS_ENABLED(CONFIG_NET_DHCPV4)) {
			net_mgmt_init_event_callback(&dhcpv4_cb,
						     event_handler,
						     DHCPV4_MASK);
			net_mgmt_add_event_callback(&dhcpv4_cb);
		}

		conn_mgr_resend_status();
	}

	/* The VLAN in this example is created for demonstration purposes.
	 */
	if (IS_ENABLED(CONFIG_NET_VLAN)) {
		ret = init_vlan();
		if (ret < 0) {
			LOG_WRN("Cannot setup VLAN (%d)", ret);
		}
	}

	/* Wait for the connection. */
	k_sem_take(&run_app, K_FOREVER);

	if (IS_ENABLED(CONFIG_NET_SAMPLE_UDP_SOCKET)) {
		ret = get_peer_address(&iface, addr_str, sizeof(addr_str));
		if (ret < 0) {
			return 0;
		}
	} else {
		struct sockaddr_ll *addr = (struct sockaddr_ll *)&data.peer;

		addr->sll_ifindex = net_if_get_by_iface(net_if_get_default());
		addr->sll_family = AF_PACKET;
		data.peer_addr_len = sizeof(struct sockaddr_ll);
		iface = net_if_get_by_index(addr->sll_ifindex);
	}

	if (!iface) {
		LOG_ERR("Cannot get local network interface!");
		return 0;
	}

	if_index = net_if_get_by_iface(iface);

	caps = net_eth_get_hw_capabilities(iface);
	if (!(caps & ETHERNET_PTP)) {
		LOG_ERR("Interface %p does not support %s", iface, "PTP");
		return 0;
	}

	if (!(caps & ETHERNET_TXTIME)) {
		LOG_ERR("Interface %p does not support %s", iface, "TXTIME");
		return 0;
	}

	data.clk = net_eth_get_ptp_clock_by_index(if_index);
	if (!data.clk) {
		LOG_ERR("Interface %p does not support %s", iface,
			"PTP clock");
		return 0;
	}

	/* Make sure the queues are enabled */
	if (IS_ENABLED(CONFIG_NET_L2_ETHERNET_MGMT) && (NET_TC_TX_COUNT > 0)) {
		enable_txtime_for_queues(iface);

		/* Set Qbv options if they are available */
		if (caps & ETHERNET_QBV) {
			set_qbv_params(iface);
		}
	}

	if (IS_ENABLED(CONFIG_NET_SAMPLE_UDP_SOCKET)) {
		LOG_INF("Socket SO_TXTIME sample to %s port %d using "
			"interface %d (%p) and PTP clock %p",
			addr_str,
			ntohs(net_sin(&data.peer)->sin_port),
			if_index, iface, data.clk);
	}

	if (IS_ENABLED(CONFIG_NET_SAMPLE_PACKET_SOCKET)) {
		LOG_INF("Socket SO_TXTIME sample using AF_PACKET and "
			"interface %d (%p) and PTP clock %p",
			if_index, iface, data.clk);
	}

	data.sock = create_socket(iface, &data.peer);
	if (data.sock < 0) {
		LOG_ERR("Cannot create socket (%d)", data.sock);
		return 0;
	}

	tx_tid = k_thread_create(&tx_thread, tx_stack,
				 K_THREAD_STACK_SIZEOF(tx_stack),
				 (k_thread_entry_t)tx, &data,
				 NULL, NULL, THREAD_PRIORITY, 0,
				 K_FOREVER);
	if (!tx_tid) {
		LOG_ERR("Cannot create TX thread!");
		return 0;
	}

	k_thread_name_set(tx_tid, "TX");

	rx_tid = k_thread_create(&rx_thread, rx_stack,
				 K_THREAD_STACK_SIZEOF(rx_stack),
				 (k_thread_entry_t)rx, &data,
				 NULL, NULL, THREAD_PRIORITY, 0,
				 K_FOREVER);
	if (!rx_tid) {
		LOG_ERR("Cannot create RX thread!");
		return 0;
	}

	k_thread_name_set(rx_tid, "RX");

	k_thread_start(rx_tid);
	k_thread_start(tx_tid);

	k_sem_take(&quit_lock, K_FOREVER);

	LOG_INF("Stopping...");

	k_thread_abort(tx_tid);
	k_thread_abort(rx_tid);

	if (data.sock >= 0) {
		(void)close(data.sock);
	}
	return 0;
}
