/*
 * Copyright (c) 2020 Synopsys, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "pktqueue.h"
#include "main.h"

static struct k_thread tthread[THREADS_NUM*QUEUE_NUM];
static struct k_thread qthread[QUEUE_NUM];

/* Each queue has its own mutex */
struct k_mutex sender_queue_mtx[QUEUE_NUM];
struct k_mutex receiver_queue_mtx[QUEUE_NUM];

/* Variable which indicates the amount of processed queues */
int queues_remain = QUEUE_NUM;
/* Variable to define current queue in thread */
int current_queue;

/* Array of packet header descriptors */
struct phdr_desc descriptors[QUEUE_NUM][SIZE_OF_QUEUE];

/* Arrays of receiver and sender queues */
struct phdr_desc_queue sender[QUEUE_NUM], receiver[QUEUE_NUM];

/* Array of packet headers */
uint8_t headers[QUEUE_NUM][SIZE_OF_QUEUE][SIZE_OF_HEADER];

static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREADS_NUM*QUEUE_NUM, STACK_SIZE);
static K_THREAD_STACK_ARRAY_DEFINE(qstack, QUEUE_NUM, STACK_SIZE);

K_MUTEX_DEFINE(fetch_queue_mtx);

/* Function for initializing "sender" packet header queue */
void init_datagram_queue(struct phdr_desc_queue *queue, int queue_num)
{
	queue->head = descriptors[queue_num];

	for (int i = 0; i < SIZE_OF_QUEUE; i++) {
		queue->tail = &descriptors[queue_num][i];
		descriptors[queue_num][i].ptr = (uint8_t *)&headers[queue_num][i];
		/* Fill packet header with random values */
		for (int j = 0; j < SIZE_OF_HEADER; j++) {
			/* leave crc field zeroed */
			if (j < CRC_BYTE_1 || j > CRC_BYTE_2) {
				descriptors[queue_num][i].ptr[j] = (uint8_t)sys_rand32_get();
			} else {
				descriptors[queue_num][i].ptr[j] = 0;
			}
		}
		/* Compute crc for further comparison */
		uint16_t crc;

		crc = crc16(POLYNOMIAL, 0x0000,
			    descriptors[queue_num][i].ptr, SIZE_OF_HEADER);

		/* Save crc value in header[CRC_BYTE_1-CRC_BYTE_2] field */
		descriptors[queue_num][i].ptr[CRC_BYTE_1] = (uint8_t)(crc >> 8);
		descriptors[queue_num][i].ptr[CRC_BYTE_2] = (uint8_t)(crc);
		queue->count++;
		descriptors[queue_num][i].next = &descriptors[queue_num][i+1];
	}
}

/* Thread takes packet from "sender" queue and puts it to "receiver" queue.
 * Each queue can be accessed only by one thread in a time. */
void test_thread(void *arg1, void *arg2, void *arg3)
{
	struct phdr_desc_queue *sender_queue = (struct phdr_desc_queue *)arg1;
	struct phdr_desc_queue *receiver_queue = (struct phdr_desc_queue *)arg2;
	struct phdr_desc *qin_ptr = NULL;
	int queue_num = *(int *)arg3;

	/* Fetching one queue */
	uint16_t crc, crc_orig;

	qin_ptr = phdr_desc_dequeue(sender_queue, &sender_queue_mtx[queue_num]);
	while (qin_ptr != NULL) {
		/* Store original crc value from header */
		crc_orig  =  qin_ptr->ptr[CRC_BYTE_1] << 8;
		crc_orig |=   qin_ptr->ptr[11];

		/* Crc field should be zero before crc calculation */
		qin_ptr->ptr[CRC_BYTE_1] = 0;
		qin_ptr->ptr[CRC_BYTE_2] = 0;
		crc = crc16(POLYNOMIAL, 0x0000, qin_ptr->ptr, SIZE_OF_HEADER);

		/* Compare computed crc with crc from phdr_desc->crc */
		if (crc == crc_orig) {
			phdr_desc_enqueue(receiver_queue, qin_ptr,
						 &receiver_queue_mtx[queue_num]);
		}
		/* Take next element from "sender queue" */
		qin_ptr = phdr_desc_dequeue(sender_queue,
						&sender_queue_mtx[queue_num]);
	}
}

/* Thread that processes one pair of sender/receiver queue */
void queue_thread(void *arg1, void *arg2, void *arg3)
{

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	int queue_num;

	/* Fetching one queue */
	k_mutex_lock(&fetch_queue_mtx, K_FOREVER);
	queue_num = current_queue;
	current_queue++;
	k_mutex_unlock(&fetch_queue_mtx);

	for (int i = 0; i < THREADS_NUM; i++)
		k_thread_create(&tthread[i+THREADS_NUM*queue_num],
			tstack[i+THREADS_NUM*queue_num], STACK_SIZE,
			(k_thread_entry_t)test_thread,
			(void *)&sender[queue_num],
			(void *)&receiver[queue_num], (void *)&queue_num,
			K_PRIO_PREEMPT(10), 0, K_NO_WAIT);

	/* Wait until sender queue is not empty */
	while (sender[queue_num].count != 0) {
		k_sleep(K_MSEC(1));
	}

	/* Decrementing queue counter */
	k_mutex_lock(&fetch_queue_mtx, K_FOREVER);
	queues_remain--;
	k_mutex_unlock(&fetch_queue_mtx);
}

void main(void)
{
	uint32_t start_time, stop_time, cycles_spent, nanoseconds_spent;

	current_queue = 0;
	printk("Simulating IP header validation on multiple cores.\n");
	printk("Each of %d parallel queues is processed by %d threads"
		" on %d cores and contain %d packet headers.\n",
		QUEUE_NUM, THREADS_NUM, arch_num_cpus(), SIZE_OF_QUEUE);
	printk("Bytes in packet header: %d\n\n", SIZE_OF_HEADER);

	/* initializing "sender" queue */
	for (int i = 0; i < QUEUE_NUM; i++) {
		init_datagram_queue(&sender[i], i);
		k_mutex_init(&sender_queue_mtx[i]);
		k_mutex_init(&receiver_queue_mtx[i]);
	}

	/* Capture initial time stamp */
	start_time = k_cycle_get_32();

	for (int i = 0; i < QUEUE_NUM; i++)
		k_thread_create(&qthread[i], qstack[i], STACK_SIZE,
				(k_thread_entry_t)queue_thread,
				(void *)&sender[i], (void *)&receiver[i],
				(void *)&i, K_PRIO_PREEMPT(11), 0, K_NO_WAIT);

	/* Wait until all queues are not processed */
	while (queues_remain > 0) {
		k_sleep(K_MSEC(1));
	}

	/* Capture final time stamp */
	stop_time = k_cycle_get_32();
	cycles_spent = stop_time - start_time;
	nanoseconds_spent = (uint32_t)k_cyc_to_ns_floor64(cycles_spent);

	/* Verify result of packet transmission
	 * The counter of correct receiver queues */
	int correct = 0;
	struct phdr_desc *tmp;
	/* Iterate and count amount of packages in receiver queues */
	for (int i = 0; i < QUEUE_NUM; i++) {
		int count = 0;

		tmp = receiver[i].head;
		while (tmp != NULL) {
			tmp = tmp->next;
			count++;
		}
		if (receiver[i].count == SIZE_OF_QUEUE && count == SIZE_OF_QUEUE) {
			correct++;
		}
	}
	if (correct == QUEUE_NUM) {
		printk("RESULT: OK\n"
			"Application ran successfully.\n"
			"All %d headers were processed in %d msec\n",
			SIZE_OF_QUEUE*QUEUE_NUM,
			nanoseconds_spent / 1000 / 1000);
	} else {
		printk("RESULT: FAIL\n"
			"Application failed.\n"
			"The amount of packets in receiver queue "
			"is less than expected.\n");
	}

	k_sleep(K_MSEC(10));
}
