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

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL);

#include <zephyr/kernel.h>

#include <zephyr/net/net_pkt.h>
#include <zephyr/net/udp.h>

#include "zperf_session.h"

#define SESSION_MAX 4

static struct session sessions[SESSION_PROTO_END][SESSION_MAX];

/* Get session from a given packet */
struct session *get_session(const struct sockaddr *addr,
			    enum session_proto proto)
{
	struct session *active = NULL;
	struct session *free = NULL;
	int i = 0;
	const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr;
	const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;

	if (proto != SESSION_TCP && proto != SESSION_UDP) {
		NET_ERR("Error! unsupported proto.\n");
		return NULL;
	}

	/* Check whether we already have an active session */
	while (!active && i < SESSION_MAX) {
		struct session *ptr = &sessions[proto][i];

		if (IS_ENABLED(CONFIG_NET_IPV4) &&
		    addr->sa_family == AF_INET &&
		    ptr->ip.family == AF_INET &&
		    ptr->port == addr4->sin_port &&
		    net_ipv4_addr_cmp(&ptr->ip.in_addr, &addr4->sin_addr)) {
			/* We found an active session */
			active = ptr;
			break;
		}

		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    addr->sa_family == AF_INET6 &&
		    ptr->ip.family == AF_INET6 &&
		    ptr->port == addr6->sin6_port &&
		    net_ipv6_addr_cmp(&ptr->ip.in6_addr, &addr6->sin6_addr)) {
			/* We found an active session */
			active = ptr;
			break;
		}

		if (!free && (ptr->state == STATE_NULL ||
			      ptr->state == STATE_COMPLETED)) {
			/* We found a free slot - just in case */
			free = ptr;
		}

		i++;
	}

	/* If no active session then create a new one */
	if (!active && free) {
		active = free;

		if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) {
			active->port = addr4->sin_port;
			active->ip.family = AF_INET;
			net_ipaddr_copy(&active->ip.in_addr, &addr4->sin_addr);
		} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
			   addr->sa_family == AF_INET6) {
			active->port = addr6->sin6_port;
			active->ip.family = AF_INET6;
			net_ipaddr_copy(&active->ip.in6_addr, &addr6->sin6_addr);
		}
	}

	return active;
}

/* TODO Unify session handling */
struct session *get_tcp_session(int sock)
{
	struct session *free = NULL;
	int i = 0;

	if (sock < 0) {
		NET_ERR("Error! Invalid socket.\n");
		return NULL;
	}

	/* Check whether we already have an active session */
	while (i < SESSION_MAX) {
		struct session *ptr = &sessions[SESSION_TCP][i];

		if (ptr->sock == sock) {
			return ptr;
		}

		if (ptr->state == STATE_NULL ||
		    ptr->state == STATE_COMPLETED) {
			/* We found a free slot - just in case */
			free = ptr;
			break;
		}

		i++;
	}

	if (free) {
		free->sock = sock;
	}

	return free;
}

void zperf_reset_session_stats(struct session *session)
{
	if (!session) {
		return;
	}

	session->counter = 0U;
	session->start_time = 0U;
	session->next_id = 0U;
	session->length = 0U;
	session->outorder = 0U;
	session->error = 0U;
	session->jitter = 0;
	session->last_transit_time = 0;
}

void zperf_session_init(void)
{
	int i, j;

	for (i = 0; i < SESSION_PROTO_END; i++) {
		for (j = 0; j < SESSION_MAX; j++) {
			sessions[i][j].state = STATE_NULL;
			zperf_reset_session_stats(&(sessions[i][j]));
		}
	}
}
