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

#include <zephyr.h>

#include <sections.h>
#include <toolchain.h>

#include <misc/printk.h>

#include <net/net_core.h>
#include <net/net_ip.h>
#include <net/nbuf.h>

#include "zperf.h"
#include "zperf_internal.h"
#include "shell_utils.h"
#include "zperf_session.h"

/* To get net_sprint_ipv{4|6}_addr() */
#define NET_LOG_ENABLED 1
#include "net_private.h"

#define TAG CMD_STR_TCP_DOWNLOAD" "

#define TCP_RX_FIBER_STACK_SIZE 1024

static char __noinit __stack zperf_tcp_rx_stack[TCP_RX_FIBER_STACK_SIZE];

#if defined(CONFIG_NET_IPV6)
static struct sockaddr_in6 *in6_addr_my;
#endif
#if defined(CONFIG_NET_IPV4)
static struct sockaddr_in *in4_addr_my;
#endif

static void tcp_received(struct net_context *context,
			 struct net_buf *buf,
			 int status,
			 void *user_data)
{
	struct session *session;
	uint32_t time;

	if (!buf) {
		return;
	}

	time = k_cycle_get_32();

	session = get_session(buf, SESSION_TCP);
	if (!session) {
		printk(TAG "ERROR! cannot get a session!\n");
		return;
	}

	switch (session->state) {
	case STATE_NULL:
	case STATE_COMPLETED:
		printk(TAG "New session started\n");
		zperf_reset_session_stats(session);
		session->start_time =  sys_cycle_get_32();
		session->state = STATE_ONGOING;
		/* fall through */
	case STATE_ONGOING:
		session->counter++;

		if (buf) {
			session->length += net_nbuf_appdatalen(buf);
		}

		if (!buf && status == 0) { /* EOF */
			uint32_t rate_in_kbps;
			uint32_t duration = HW_CYCLES_TO_USEC(
				time_delta(session->start_time, time));

			session->state = STATE_COMPLETED;

			/* Compute baud rate */
			if (duration != 0) {
				rate_in_kbps = (uint32_t)
					(((uint64_t)session->length *
					  (uint64_t)8 *
					  (uint64_t)USEC_PER_SEC) /
					 ((uint64_t)duration * 1024));
			} else {
				rate_in_kbps = 0;
			}

			printk(TAG "TCP session ended\n");

			printk(TAG " duration:\t\t");
			print_number(duration, TIME_US, TIME_US_UNIT);
			printk("\n");

			printk(TAG " rate:\t\t\t");
			print_number(rate_in_kbps, KBPS, KBPS_UNIT);
			printk("\n");
		}
		break;
	case STATE_LAST_PACKET_RECEIVED:
		break;
	default:
		printk(TAG "Error! Unsupported case\n");
	}

	net_nbuf_unref(buf);
}

static void tcp_accepted(struct net_context *context,
			 struct sockaddr *addr,
			 socklen_t addrlen,
			 int error,
			 void *user_data)
{
	int ret;

	ret = net_context_recv(context, tcp_received, K_NO_WAIT, user_data);
	if (ret < 0) {
		printk(TAG "Cannot receive TCP packet (family %d)",
			net_context_get_family(context));
	}
}

static void zperf_tcp_rx_thread(int port)
{
#if defined(CONFIG_NET_IPV4)
	struct net_context *context4 = NULL;
#endif
#if defined(CONFIG_NET_IPV6)
	struct net_context *context6 = NULL;
#endif
	int ret, fail = 0;

#if defined(CONFIG_NET_IPV4) && defined(MY_IP4ADDR)
	ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &context4);
	if (ret < 0) {
		printk(TAG "ERROR! Cannot get IPv4 TCP network context.\n");
		return;
	}

	ret = zperf_get_ipv4_addr(MY_IP4ADDR, &in4_addr_my->sin_addr, TAG);
	if (ret < 0) {
		printk(TAG "ERROR! Unable to set IPv4\n");
		return;
	}

	printk(TAG "Binding to %s\n",
	       net_sprint_ipv4_addr(&in4_addr_my->sin_addr));

	in4_addr_my->sin_port = htons(port);
#endif

#if defined(CONFIG_NET_IPV6) && defined(MY_IP6ADDR)
	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, &context6);
	if (ret < 0) {
		printk(TAG "ERROR! Cannot get IPv6 TCP network context.\n");
		return;
	}

	ret = zperf_get_ipv6_addr(MY_IP6ADDR, MY_PREFIX_LEN_STR,
				  &in6_addr_my->sin6_addr, TAG);
	if (ret < 0) {
		printk(TAG "ERROR! Unable to set IPv6\n");
		return;
	}

	printk(TAG "Binding to %s\n",
	       net_sprint_ipv6_addr(&in6_addr_my->sin6_addr));

	in6_addr_my->sin6_port = htons(port);
#endif

#if defined(CONFIG_NET_IPV6)
	if (context6) {
		ret = net_context_bind(context6,
				       (struct sockaddr *)in6_addr_my,
				       sizeof(struct sockaddr_in6));
		if (ret < 0) {
			printk(TAG "Cannot bind IPv6 TCP port %d (%d)\n",
			       ntohs(in6_addr_my->sin6_port), ret);
			fail++;
		}

		ret = net_context_listen(context6, 0);
		if (ret < 0) {
			printk(TAG "Cannot listen IPv6 TCP (%d)", ret);
			return;
		}

		ret = net_context_accept(context6, tcp_accepted, 0, NULL);
		if (ret < 0) {
			printk(TAG "Cannot receive IPv6 TCP packets (%d)", ret);
			return;
		}
	}
#endif

#if defined(CONFIG_NET_IPV4)
	if (context4) {
		ret = net_context_bind(context4,
				       (struct sockaddr *)in4_addr_my,
				       sizeof(struct sockaddr_in));
		if (ret < 0) {
			printk(TAG "Cannot bind IPv4 TCP port %d (%d)\n",
			       ntohs(in4_addr_my->sin_port), ret);
			fail++;
		}

		ret = net_context_listen(context4, 0);
		if (ret < 0) {
			printk(TAG "Cannot listen IPv4 TCP (%d)", ret);
			return;
		}

		ret = net_context_accept(context4, tcp_accepted, 0, NULL);
		if (ret < 0) {
			printk(TAG "Cannot receive IPv4 TCP packets (%d)", ret);
			return;
		}
	}
#endif

	if (fail > 1) {
		return;
	}

	k_sleep(K_FOREVER);
}

void zperf_tcp_receiver_init(int port)
{
#if defined(CONFIG_NET_IPV6)
	in6_addr_my = zperf_get_sin6();
#endif
#if defined(CONFIG_NET_IPV4)
	in4_addr_my = zperf_get_sin();
#endif

	k_thread_spawn(zperf_tcp_rx_stack, sizeof(zperf_tcp_rx_stack),
		       (k_thread_entry_t)zperf_tcp_rx_thread,
		       INT_TO_POINTER(port), 0, 0,
		       K_PRIO_COOP(7), 0, K_NO_WAIT);
}
