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

#include <zephyr/ztest.h>
#include "lifo_usage.h"
#include <zephyr/kernel.h>

#define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define LIST_LEN 2

struct k_lifo lifo, plifo;
static ldata_t lifo_data[LIST_LEN];
struct k_lifo timeout_order_lifo;

static struct k_thread tdata, tdata1;
static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
static K_THREAD_STACK_DEFINE(tstack1, STACK_SIZE);

static struct k_sem start_sema, wait_sema;
void test_thread_pend_and_timeout(void *p1, void *p2, void *p3);

struct scratch_lifo_packet {
	void *link_in_lifo;
	void *data_if_needed;
};

struct reply_packet {
	void *link_in_lifo;
	int32_t reply;
};

struct timeout_order_data {
	void *link_in_lifo;
	struct k_lifo *klifo;
	int32_t timeout;
	int32_t timeout_order;
	int32_t q_order;
};

static struct k_lifo lifo_timeout[2];

struct timeout_order_data timeout_order_data[] = {
	{0, &lifo_timeout[0], 200, 2, 0},
	{0, &lifo_timeout[0], 400, 4, 1},
	{0, &lifo_timeout[0],   0, 0, 2},
	{0, &lifo_timeout[0], 100, 1, 3},
	{0, &lifo_timeout[0], 300, 3, 4},
};

struct timeout_order_data timeout_order_data_mult_lifo[] = {
	{0, &lifo_timeout[1],   0, 0, 0},
	{0, &lifo_timeout[0], 300, 3, 1},
	{0, &lifo_timeout[0], 500, 5, 2},
	{0, &lifo_timeout[1], 800, 8, 3},
	{0, &lifo_timeout[1], 700, 7, 4},
	{0, &lifo_timeout[0], 100, 1, 5},
	{0, &lifo_timeout[0], 600, 6, 6},
	{0, &lifo_timeout[0], 200, 2, 7},
	{0, &lifo_timeout[1], 400, 4, 8},
};

#define NUM_SCRATCH_LIFO_PACKETS 20
#define TIMEOUT_ORDER_NUM_THREADS	ARRAY_SIZE(timeout_order_data_mult_lifo)
#define TSTACK_SIZE			(1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define LIFO_THREAD_PRIO		-5

struct scratch_lifo_packet scratch_lifo_packets[NUM_SCRATCH_LIFO_PACKETS];

struct k_lifo scratch_lifo_packets_lifo;

static k_tid_t to_ord_tid[TIMEOUT_ORDER_NUM_THREADS];
static K_THREAD_STACK_ARRAY_DEFINE(ttstack,
		TIMEOUT_ORDER_NUM_THREADS, TSTACK_SIZE);
static struct k_thread ttdata[TIMEOUT_ORDER_NUM_THREADS];

static void *get_scratch_packet(void)
{
	void *packet = k_lifo_get(&scratch_lifo_packets_lifo, K_NO_WAIT);

	zassert_true(packet != NULL);
	return packet;
}

static void put_scratch_packet(void *packet)
{
	k_lifo_put(&scratch_lifo_packets_lifo, packet);
}

static void thread_entry_nowait(void *p1, void *p2, void *p3)
{
	void *ret;

	ret = k_lifo_get((struct k_lifo *)p1, K_FOREVER);

	/* data pushed at last should be read first */
	zassert_equal(ret, (void *)&lifo_data[1]);

	ret = k_lifo_get((struct k_lifo *)p1, K_FOREVER);

	zassert_equal(ret, (void *)&lifo_data[0]);

	k_sem_give(&start_sema);
}

static bool is_timeout_in_range(uint32_t start_time, uint32_t timeout)
{
	uint32_t stop_time, diff;

	stop_time = k_cycle_get_32();
	diff = k_cyc_to_ms_floor32(stop_time - start_time);
	return timeout <= diff;
}

static int test_multiple_threads_pending(struct timeout_order_data *test_data,
					 int test_data_size)
{
	int ii;

	for (ii = 0; ii < test_data_size; ii++) {
		to_ord_tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
						 test_thread_pend_and_timeout,
						 &test_data[ii], NULL, NULL,
						 LIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);
	}

	for (ii = 0; ii < test_data_size; ii++) {
		struct timeout_order_data *data =
			k_lifo_get(&timeout_order_lifo, K_FOREVER);

		if (data->timeout_order == ii) {
			TC_PRINT(" thread (q order: %d, t/o: %d, lifo %p)\n",
				 data->q_order, (int) data->timeout,
				 data->klifo);
		} else {
			zassert_equal(data->timeout_order, ii, " *** thread %d "
				      "woke up, expected %d\n",
				      data->timeout_order, ii);
			return TC_FAIL;
		}
	}

	return TC_PASS;
}

static void thread_entry_wait(void *p1, void *p2, void *p3)
{
	k_lifo_put((struct k_lifo *)p1, (void *)&lifo_data[0]);

	k_lifo_put((struct k_lifo *)p1, (void *)&lifo_data[1]);
	k_sem_give(&wait_sema);
}

/**
 * @brief LIFOs
 * @defgroup kernel_lifo_tests LIFOs
 * @ingroup all_tests
 * @{
 * @}
 */

/**
 * @addtogroup kernel_lifo_tests
 * @{
 */

/**
 * @brief try getting data on lifo with special timeout value,
 * return result in lifo
 *
 *
 * @see k_lifo_put()
 */
static void test_thread_timeout_reply_values(void *p1, void *p2, void *p3)
{
	struct reply_packet *reply_packet = (struct reply_packet *)p1;

	reply_packet->reply =
		!!k_lifo_get(&lifo_timeout[0], K_NO_WAIT);

	k_lifo_put(&timeout_order_lifo, reply_packet);
}

/**
 * @see k_lifo_put()
 */
static void test_thread_timeout_reply_values_wfe(void *p1, void *p2, void *p3)
{
	struct reply_packet *reply_packet = (struct reply_packet *)p1;

	reply_packet->reply =
		!!k_lifo_get(&lifo_timeout[0], K_FOREVER);

	k_lifo_put(&timeout_order_lifo, reply_packet);
}

/**
 * @brief A thread sleeps then puts data on the lifo
 *
 * @see k_lifo_put()
 */
static void test_thread_put_timeout(void *p1, void *p2, void *p3)
{
	uint32_t timeout = *((uint32_t *)p2);

	k_msleep(timeout);
	k_lifo_put((struct k_lifo *)p1, get_scratch_packet());
}

/**
 * @brief Test last in, first out queue using LIFO
 * @see k_sem_init(), k_lifo_put(), k_lifo_get()
 */
ZTEST(lifo_usage, test_lifo_nowait)
{
	k_lifo_init(&lifo);

	k_sem_init(&start_sema, 0, 1);

	/* put some data on lifo */
	k_lifo_put(&lifo, (void *)&lifo_data[0]);

	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      thread_entry_nowait, &lifo, NULL, NULL,
				      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	k_lifo_put(&lifo, (void *)&lifo_data[1]);

	/* Allow another thread to read lifo */
	k_sem_take(&start_sema, K_FOREVER);
	k_thread_abort(tid);
}

/**
 * @brief Test pending reader in LIFO
 * @see k_lifo_init(), k_lifo_get(), k_lifo_put()
 */
ZTEST(lifo_usage_1cpu, test_lifo_wait)
{
	int *ret;

	k_lifo_init(&plifo);
	k_sem_init(&wait_sema, 0, 1);

	k_tid_t tid = k_thread_create(&tdata1, tstack1, STACK_SIZE,
				      thread_entry_wait, &plifo, NULL, NULL,
				      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	ret = k_lifo_get(&plifo, K_FOREVER);

	zassert_equal(ret, (void *)&lifo_data[0]);

	k_sem_take(&wait_sema, K_FOREVER);

	ret = k_lifo_get(&plifo, K_FOREVER);

	zassert_equal(ret, (void *)&lifo_data[1]);

	k_thread_abort(tid);
}

/**
 * @brief Test reading empty LIFO
 * @see k_lifo_get()
 */
ZTEST(lifo_usage_1cpu, test_timeout_empty_lifo)
{
	void *packet;

	uint32_t start_time, timeout;

	timeout = 100U;

	start_time = k_cycle_get_32();

	packet = k_lifo_get(&lifo_timeout[0], K_MSEC(timeout));

	zassert_is_null(packet);

	zassert_true(is_timeout_in_range(start_time, timeout));

	/* Test empty lifo with timeout of K_NO_WAIT */
	packet = k_lifo_get(&lifo_timeout[0], K_NO_WAIT);
	zassert_is_null(packet);
}

/**
 * @brief Test read and write operation in LIFO with timeout
 * @see k_lifo_put(), k_lifo_get()
 */
ZTEST(lifo_usage, test_timeout_non_empty_lifo)
{
	void *packet, *scratch_packet;

	/* Test k_lifo_get with K_NO_WAIT */
	scratch_packet = get_scratch_packet();
	k_lifo_put(&lifo_timeout[0], scratch_packet);
	packet = k_lifo_get(&lifo_timeout[0], K_NO_WAIT);
	zassert_true(packet != NULL);
	put_scratch_packet(scratch_packet);

	 /* Test k_lifo_get with K_FOREVER */
	scratch_packet = get_scratch_packet();
	k_lifo_put(&lifo_timeout[0], scratch_packet);
	packet = k_lifo_get(&lifo_timeout[0], K_FOREVER);
	zassert_true(packet != NULL);
}

/**
 * @brief Test LIFO with timeout
 * @see k_lifo_put(), k_lifo_get()
 */
ZTEST(lifo_usage_1cpu, test_timeout_lifo_thread)
{
	void *packet, *scratch_packet;
	static volatile struct reply_packet reply_packet;
	uint32_t start_time, timeout;

	/*
	 * Test lifo with some timeout and child thread that puts
	 * data on the lifo on time
	 */
	timeout = 10U;
	start_time = k_cycle_get_32();

	to_ord_tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
					test_thread_put_timeout, &lifo_timeout[0],
					&timeout, NULL,
					LIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);

	packet = k_lifo_get(&lifo_timeout[0], K_MSEC(timeout + 10));
	zassert_true(packet != NULL);
	zassert_true(is_timeout_in_range(start_time, timeout));
	put_scratch_packet(packet);

	/*
	 * Test k_lifo_get with timeout of K_NO_WAIT and the lifo
	 * should be filled be filled by the child thread based on
	 * the data availability on another lifo. In this test child
	 * thread does not find data on lifo.
	 */
	to_ord_tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
					test_thread_timeout_reply_values,
					(void *)&reply_packet, NULL, NULL,
					LIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);

	k_yield();
	packet = k_lifo_get(&timeout_order_lifo, K_NO_WAIT);
	zassert_true(packet != NULL);
	zassert_false(reply_packet.reply);

	/*
	 * Test k_lifo_get with timeout of K_NO_WAIT and the lifo
	 * should be filled be filled by the child thread based on
	 * the data availability on another lifo. In this test child
	 * thread does find data on lifo.
	 */
	scratch_packet = get_scratch_packet();
	k_lifo_put(&lifo_timeout[0], scratch_packet);

	to_ord_tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
					test_thread_timeout_reply_values,
					(void *)&reply_packet, NULL, NULL,
					LIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);

	k_yield();
	packet = k_lifo_get(&timeout_order_lifo, K_NO_WAIT);
	zassert_true(packet != NULL);
	zassert_true(reply_packet.reply);
	put_scratch_packet(scratch_packet);

	/*
	 * Test k_lifo_get with timeout of K_FOREVER and the lifo
	 * should be filled be filled by the child thread based on
	 * the data availability on another lifo. In this test child
	 * thread does find data on lifo.
	 */
	scratch_packet = get_scratch_packet();
	k_lifo_put(&lifo_timeout[0], scratch_packet);

	to_ord_tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
					test_thread_timeout_reply_values_wfe,
					(void *)&reply_packet, NULL, NULL,
					LIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);

	packet = k_lifo_get(&timeout_order_lifo, K_FOREVER);
	zassert_true(packet != NULL);
	zassert_true(reply_packet.reply);
	put_scratch_packet(scratch_packet);
}

/**
 * @brief a thread pends on a lifo then times out
 * @see k_lifo_put(), k_lifo_get()
 */
void test_thread_pend_and_timeout(void *p1, void *p2, void *p3)
{
	struct timeout_order_data *d = (struct timeout_order_data *)p1;
	uint32_t start_time;
	void *packet;

	start_time = k_cycle_get_32();
	packet = k_lifo_get(d->klifo, K_MSEC(d->timeout));
	zassert_true(packet == NULL);
	zassert_true(is_timeout_in_range(start_time, d->timeout));

	k_lifo_put(&timeout_order_lifo, d);
}


/**
 * @brief Test multiple pending readers in LIFO
 * @details test multiple threads pending on the same lifo
 * with different timeouts
 * @see k_lifo_get()
 */
ZTEST(lifo_usage_1cpu, test_timeout_threads_pend_on_lifo)
{
	int32_t rv, test_data_size;

	/*
	 * Test multiple threads pending on the same
	 * lifo with different timeouts
	 */
	test_data_size = ARRAY_SIZE(timeout_order_data);
	rv = test_multiple_threads_pending(timeout_order_data, test_data_size);
	zassert_equal(rv, TC_PASS);
}

/**
 * @brief Test LIFO initialization with various parameters
 * @see k_lifo_init(), k_lifo_put()
 */
static void test_para_init(void)
{
	intptr_t ii;

	/* Init  kernel objects*/
	k_lifo_init(&lifo_timeout[0]);

	k_lifo_init(&lifo_timeout[0]);

	k_lifo_init(&timeout_order_lifo);

	k_lifo_init(&scratch_lifo_packets_lifo);

	/* Fill Scratch LIFO*/

	for (ii = 0; ii < NUM_SCRATCH_LIFO_PACKETS; ii++) {
		scratch_lifo_packets[ii].data_if_needed = (void *)ii;
		k_lifo_put(&scratch_lifo_packets_lifo,
				(void *)&scratch_lifo_packets[ii]);
	}

	for (int i = 0; i < LIST_LEN; i++) {
		lifo_data[i].data = i + 1;
	}
}

/**
 * @}
 */

/** test case main entry */
void *lifo_usage_setup(void)
{
	test_para_init();

	return NULL;
}


ZTEST_SUITE(lifo_usage_1cpu, NULL, lifo_usage_setup,
		ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);

ZTEST_SUITE(lifo_usage, NULL, lifo_usage_setup, NULL, NULL, NULL);
