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

#include <ztest.h>
#include <irq_offload.h>
#include <ksched.h>
#include <misc/__assert.h>
#include <misc/util.h>

/*
 * @file
 * @brief Test fifo APIs timeout
 *
 * This module tests following fifo timeout scenarios
 *
 * First, the thread waits with a timeout and times out. Then it wait with a
 * timeout, but gets the data in time.
 *
 * Then, multiple timeout tests are done for the threads, to test the ordering
 * of queueing/dequeueing when timeout occurs, first on one fifo, then on
 * multiple fifos.
 *
 * Finally, multiple threads pend on one fifo, and they all get the
 * data in time, except the last one: this tests that the timeout is
 * recomputed correctly when timeouts are aborted.
 */

struct scratch_fifo_packet {
	void *link_in_fifo;
	void *data_if_needed;
};

struct reply_packet {
	void *link_in_fifo;
	s32_t reply;
};

struct timeout_order_data {
	void *link_in_fifo;
	struct k_fifo *fifo;
	u32_t timeout;
	s32_t timeout_order;
	s32_t q_order;
};


#define NUM_SCRATCH_FIFO_PACKETS 20
struct scratch_fifo_packet scratch_fifo_packets[NUM_SCRATCH_FIFO_PACKETS];

struct k_fifo scratch_fifo_packets_fifo;

static struct k_fifo fifo_timeout[2];
struct k_fifo timeout_order_fifo;

struct timeout_order_data timeout_order_data[] = {
	{0, &fifo_timeout[0], 20, 2, 0},
	{0, &fifo_timeout[0], 40, 4, 1},
	{0, &fifo_timeout[0], 0, 0, 2},
	{0, &fifo_timeout[0], 10, 1, 3},
	{0, &fifo_timeout[0], 30, 3, 4},
};

struct timeout_order_data timeout_order_data_mult_fifo[] = {
	{0, &fifo_timeout[1], 0, 0, 0},
	{0, &fifo_timeout[0], 30, 3, 1},
	{0, &fifo_timeout[0], 50, 5, 2},
	{0, &fifo_timeout[1], 80, 8, 3},
	{0, &fifo_timeout[1], 70, 7, 4},
	{0, &fifo_timeout[0], 10, 1, 5},
	{0, &fifo_timeout[0], 60, 6, 6},
	{0, &fifo_timeout[0], 20, 2, 7},
	{0, &fifo_timeout[1], 40, 4, 8},
};

#define TIMEOUT_ORDER_NUM_THREADS	ARRAY_SIZE(timeout_order_data_mult_fifo)
#define TSTACK_SIZE			1024
#define FIFO_THREAD_PRIO		-5

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

static void *get_scratch_packet(void)
{
	void *packet = k_fifo_get(&scratch_fifo_packets_fifo, K_NO_WAIT);

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

static void put_scratch_packet(void *packet)
{
	k_fifo_put(&scratch_fifo_packets_fifo, packet);
}

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

	stop_time = k_cycle_get_32();
	diff = SYS_CLOCK_HW_CYCLES_TO_NS(stop_time -
			start_time) / NSEC_PER_USEC;
	diff = diff / USEC_PER_MSEC;
	return timeout <= diff;
}

/* a thread sleeps then puts data on the fifo */
static void test_thread_put_timeout(void *p1, void *p2, void *p3)
{
	u32_t timeout = *((u32_t *)p2);

	k_sleep(timeout);
	k_fifo_put((struct k_fifo *)p1, get_scratch_packet());
}

/* a thread pends on a fifo then times out */
static void test_thread_pend_and_timeout(void *p1, void *p2, void *p3)
{
	struct timeout_order_data *d = (struct timeout_order_data *)p1;
	u32_t start_time;
	void *packet;

	start_time = k_cycle_get_32();
	packet = k_fifo_get(d->fifo, d->timeout);
	zassert_true(packet == NULL, NULL);
	zassert_true(is_timeout_in_range(start_time, d->timeout), NULL);

	k_fifo_put(&timeout_order_fifo, d);
}
/* Spins several threads that pend and timeout on fifos */
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++) {
		tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
				test_thread_pend_and_timeout,
				&test_data[ii], NULL, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, 0);
	}

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

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

	return TC_PASS;
}

/* a thread pends on a fifo with a timeout and gets the data in time */
static void test_thread_pend_and_get_data(void *p1, void *p2, void *p3)
{
	struct timeout_order_data *d = (struct timeout_order_data *)p1;
	void *packet;

	packet = k_fifo_get(d->fifo, d->timeout);
	zassert_true(packet != NULL, NULL);

	put_scratch_packet(packet);
	k_fifo_put(&timeout_order_fifo, d);
}

/* Spins child threads that get fifo data in time, except the last one */
static int test_multiple_threads_get_data(struct timeout_order_data *test_data,
					 int test_data_size)
{
	struct timeout_order_data *data;
	int ii;

	for (ii = 0; ii < test_data_size-1; ii++) {
		tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
				test_thread_pend_and_get_data,
				&test_data[ii], NULL, NULL,
				K_PRIO_PREEMPT(0), K_INHERIT_PERMS, 0);
	}

	tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
				test_thread_pend_and_timeout,
				&test_data[ii], NULL, NULL,
				K_PRIO_PREEMPT(0), K_INHERIT_PERMS, 0);

	for (ii = 0; ii < test_data_size-1; ii++) {

		k_fifo_put(test_data[ii].fifo, get_scratch_packet());

		data = k_fifo_get(&timeout_order_fifo, K_FOREVER);

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

	data = k_fifo_get(&timeout_order_fifo, K_FOREVER);
	if (data->q_order == ii) {
		TC_PRINT(" thread (q order: %d, t/o: %d, fifo %p)\n",
				data->q_order, data->timeout, data->fifo);
	} else {
		TC_ERROR(" *** thread %d woke up, expected %d\n",
					data->timeout_order, ii);
		return TC_FAIL;
	}

	return TC_PASS;
}

/* try getting data on fifo with special timeout value, return result in fifo */
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_fifo_get(&fifo_timeout[0], K_NO_WAIT);

	k_fifo_put(&timeout_order_fifo, reply_packet);
}

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_fifo_get(&fifo_timeout[0], K_FOREVER);

	k_fifo_put(&timeout_order_fifo, reply_packet);
}

/*test cases*/
static void test_timeout_empty_fifo(void)
{
	void *packet;
	u32_t start_time, timeout;

	/* Test empty fifo with timeout */
	timeout = 10;
	start_time = k_cycle_get_32();
	packet = k_fifo_get(&fifo_timeout[0], timeout);
	zassert_true(packet == NULL, NULL);
	zassert_true(is_timeout_in_range(start_time, timeout), NULL);

	/* Test empty fifo with timeout of K_NO_WAIT */
	packet = k_fifo_get(&fifo_timeout[0], K_NO_WAIT);
	zassert_true(packet == NULL, NULL);
}

static void test_timeout_non_empty_fifo(void)
{
	void *packet, *scratch_packet;

	 /* Test k_fifo_get with K_NO_WAIT */
	scratch_packet = get_scratch_packet();
	k_fifo_put(&fifo_timeout[0], scratch_packet);
	packet = k_fifo_get(&fifo_timeout[0], K_NO_WAIT);
	zassert_true(packet != NULL, NULL);
	put_scratch_packet(scratch_packet);

	 /* Test k_fifo_get with K_FOREVER */
	scratch_packet = get_scratch_packet();
	k_fifo_put(&fifo_timeout[0], scratch_packet);
	packet = k_fifo_get(&fifo_timeout[0], K_FOREVER);
	zassert_true(packet != NULL, NULL);
	put_scratch_packet(scratch_packet);
}

static void test_timeout_fifo_thread(void)
{
	void *packet, *scratch_packet;
	struct reply_packet reply_packet;
	u32_t start_time, timeout;

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

	tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
				test_thread_put_timeout, &fifo_timeout[0],
				&timeout, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, 0);

	packet = k_fifo_get(&fifo_timeout[0], timeout + 10);
	zassert_true(packet != NULL, NULL);
	zassert_true(is_timeout_in_range(start_time, timeout), NULL);
	put_scratch_packet(packet);

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

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

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

	tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
				test_thread_timeout_reply_values,
				&reply_packet, NULL, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, 0);

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

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

	tid[0] = k_thread_create(&ttdata[0], ttstack[0], TSTACK_SIZE,
				test_thread_timeout_reply_values_wfe,
				&reply_packet, NULL, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, 0);

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

static void test_timeout_threads_pend_on_fifo(void)
{
	s32_t rv, test_data_size;

	/*
	 * Test multiple threads pending on the same
	 * fifo 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, NULL);
}

static void test_timeout_threads_pend_on_dual_fifos(void)
{
	s32_t rv, test_data_size;

	/*
	 * Test multiple threads pending on different
	 * fifos with different timeouts
	 */
	test_data_size = ARRAY_SIZE(timeout_order_data_mult_fifo);
	rv = test_multiple_threads_pending(timeout_order_data_mult_fifo,
							test_data_size);
	zassert_equal(rv, TC_PASS, NULL);

}

static void test_timeout_threads_pend_fail_on_fifo(void)
{
	s32_t rv, test_data_size;

	/*
	 * Test multiple threads pending on same
	 * fifo with different timeouts, but getting
	 * the data in time, except the last one.
	 */
	test_data_size = ARRAY_SIZE(timeout_order_data);
	rv = test_multiple_threads_get_data(timeout_order_data, test_data_size);
	zassert_equal(rv, TC_PASS, NULL);
}

static void test_timeout_setup(void)
{
	s32_t ii;

	/* Init kernel objects */
	k_fifo_init(&fifo_timeout[0]);
	k_fifo_init(&fifo_timeout[1]);
	k_fifo_init(&timeout_order_fifo);
	k_fifo_init(&scratch_fifo_packets_fifo);

	/* Fill scratch fifo */
	for (ii = 0; ii < NUM_SCRATCH_FIFO_PACKETS; ii++) {
		scratch_fifo_packets[ii].data_if_needed = (void *)ii;
		k_fifo_put(&scratch_fifo_packets_fifo,
				(void *)&scratch_fifo_packets[ii]);
	}

}

/*test case main entry*/
void test_main(void)
{
	test_timeout_setup();

	ztest_test_suite(test_fifo_timeout,
		ztest_unit_test(test_timeout_empty_fifo),
		ztest_unit_test(test_timeout_non_empty_fifo),
		ztest_unit_test(test_timeout_fifo_thread),
		ztest_unit_test(test_timeout_threads_pend_on_fifo),
		ztest_unit_test(test_timeout_threads_pend_on_dual_fifos),
		ztest_unit_test(test_timeout_threads_pend_fail_on_fifo));
	ztest_run_test_suite(test_fifo_timeout);
}
