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

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_zperf_sample, LOG_LEVEL_DBG);

#include <zephyr/zephyr.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) {
		printk("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) {
		printk("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]));
		}
	}
}
