/*
 * Copyright (c) 2015 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zephyr.h>
#include <tc_util.h>
#include <misc/__assert.h>
#include <misc/util.h>

/* timeout tests
 *
 * Test the nano_xxx_fifo_wait_timeout() APIs.
 *
 * First, the task 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 fibers, to test the ordering
 * of queueing/dequeueing when timeout occurs, first on one fifo, then on
 * multiple fifos.
 *
 * Finally, multiple fibers 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.
 */

#include <tc_nano_timeout_common.h>

#define FIBER_PRIORITY 5
#ifndef FIBER_STACKSIZE
#define FIBER_STACKSIZE 2048
#endif

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

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

#define NUM_SCRATCH_FIFO_PACKETS 20
struct scratch_fifo_packet scratch_fifo_packets[NUM_SCRATCH_FIFO_PACKETS];

struct nano_fifo scratch_fifo_packets_fifo;

void *get_scratch_packet(void)
{
	void *packet = nano_fifo_get(&scratch_fifo_packets_fifo, TICKS_NONE);

	__ASSERT_NO_MSG(packet);

	return packet;
}

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

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

struct timeout_order_data {
	void *link_in_fifo;
	struct nano_fifo *fifo;
	int32_t timeout;
	int timeout_order;
	int q_order;
};


struct timeout_order_data timeout_order_data[] = {
	{0, &fifo_timeout[0], TIMEOUT(2), 2, 0},
	{0, &fifo_timeout[0], TIMEOUT(4), 4, 1},
	{0, &fifo_timeout[0], TIMEOUT(0), 0, 2},
	{0, &fifo_timeout[0], TIMEOUT(1), 1, 3},
	{0, &fifo_timeout[0], TIMEOUT(3), 3, 4},
};

struct timeout_order_data timeout_order_data_mult_fifo[] = {
	{0, &fifo_timeout[1], TIMEOUT(0), 0, 0},
	{0, &fifo_timeout[0], TIMEOUT(3), 3, 1},
	{0, &fifo_timeout[0], TIMEOUT(5), 5, 2},
	{0, &fifo_timeout[1], TIMEOUT(8), 8, 3},
	{0, &fifo_timeout[1], TIMEOUT(7), 7, 4},
	{0, &fifo_timeout[0], TIMEOUT(1), 1, 5},
	{0, &fifo_timeout[0], TIMEOUT(6), 6, 6},
	{0, &fifo_timeout[0], TIMEOUT(2), 2, 7},
	{0, &fifo_timeout[1], TIMEOUT(4), 4, 8},
};

#define TIMEOUT_ORDER_NUM_FIBERS ARRAY_SIZE(timeout_order_data_mult_fifo)
static char __stack timeout_stacks[TIMEOUT_ORDER_NUM_FIBERS][FIBER_STACKSIZE];

/* a fiber sleeps then puts data on the fifo */
static void test_fiber_put_timeout(int fifo, int timeout)
{
	fiber_sleep((int32_t)timeout);
	nano_fiber_fifo_put((struct nano_fifo *)fifo, get_scratch_packet());
}

/* a fiber pends on a fifo then times out */
static void test_fiber_pend_and_timeout(int data, int unused)
{
	struct timeout_order_data *d = (void *)data;
	int32_t orig_ticks = sys_tick_get();
	void *packet;

	ARG_UNUSED(unused);

	packet = nano_fiber_fifo_get(d->fifo, d->timeout);
	if (packet) {
		TC_ERROR(" *** timeout of %d did not time out.\n",
					d->timeout);
		return;
	}
	if (!is_timeout_in_range(orig_ticks, d->timeout)) {
		return;
	}

	nano_fiber_fifo_put(&timeout_order_fifo, d);
}

/* the task spins several fibers that pend and timeout on fifos */
static int test_multiple_fibers_pending(struct timeout_order_data *test_data,
										int test_data_size)
{
	int ii;

	for (ii = 0; ii < test_data_size; ii++) {
		task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
							test_fiber_pend_and_timeout,
							(int)&test_data[ii], 0,
							FIBER_PRIORITY, 0);
	}

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

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

	return TC_PASS;
}

/* a fiber pends on a fifo with a timeout and gets the data in time */
static void test_fiber_pend_and_get_data(int data, int unused)
{
	struct timeout_order_data *d = (void *)data;
	void *packet;

	ARG_UNUSED(unused);

	packet = nano_fiber_fifo_get(d->fifo, d->timeout);
	if (!packet) {
		TC_PRINT(" *** fiber (q order: %d, t/o: %d, fifo %p) timed out!\n",
						d->q_order, d->timeout, d->fifo);
		return;
	}

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

/* the task spins fibers that get fifo data in time, except the last one */
static int test_multiple_fibers_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++) {
		task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
							test_fiber_pend_and_get_data,
							(int)&test_data[ii], 0,
							FIBER_PRIORITY, 0);
	}
	task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
						test_fiber_pend_and_timeout,
						(int)&test_data[ii], 0,
						FIBER_PRIORITY, 0);

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

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

		data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);

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

	data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);
	if (data->q_order == ii) {
		TC_PRINT(" got fiber (q order: %d, t/o: %d, fifo %p) as expected\n",
					data->q_order, data->timeout, data->fifo);
	} else {
		TC_ERROR(" *** fiber %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_fiber_ticks_special_values(int packet, int special_value)
{
	struct reply_packet *reply_packet = (void *)packet;

	reply_packet->reply =
		!!nano_fiber_fifo_get(&fifo_timeout[0], special_value);

	nano_fiber_fifo_put(&timeout_order_fifo, reply_packet);
}

/* the timeout test entry point */
int test_fifo_timeout(void)
{
	int64_t orig_ticks;
	int32_t timeout;
	int rv;
	void *packet, *scratch_packet;
	int test_data_size;
	int ii;
	struct reply_packet reply_packet;

	nano_fifo_init(&fifo_timeout[0]);
	nano_fifo_init(&fifo_timeout[1]);
	nano_fifo_init(&timeout_order_fifo);
	nano_fifo_init(&scratch_fifo_packets_fifo);

	for (ii = 0; ii < NUM_SCRATCH_FIFO_PACKETS; ii++) {
		scratch_fifo_packets[ii].data_if_needed = (void *)ii;
		nano_task_fifo_put(&scratch_fifo_packets_fifo,
							&scratch_fifo_packets[ii]);
	}

	/* test nano_task_fifo_get() with timeout */
	timeout = 10;
	orig_ticks = sys_tick_get();
	packet = nano_task_fifo_get(&fifo_timeout[0], timeout);
	if (packet) {
		TC_ERROR(" *** timeout of %d did not time out.\n", timeout);
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}
	if ((sys_tick_get() - orig_ticks) < timeout) {
		TC_ERROR(" *** task did not wait long enough on timeout of %d.\n",
					timeout);
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	/* test nano_task_fifo_get with timeout of 0 */

	packet = nano_task_fifo_get(&fifo_timeout[0], 0);
	if (packet) {
		TC_ERROR(" *** timeout of 0 did not time out.\n");
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	/* test nano_task_fifo_get with timeout > 0 */

	TC_PRINT("test nano_task_fifo_get with timeout > 0\n");

	timeout = 3;
	orig_ticks = sys_tick_get();

	packet = nano_task_fifo_get(&fifo_timeout[0], timeout);

	if (packet) {
		TC_ERROR(" *** timeout of %d did not time out.\n",
				timeout);
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	if (!is_timeout_in_range(orig_ticks, timeout)) {
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	TC_PRINT("nano_task_fifo_get timed out as expected\n");

	/*
	 * test nano_task_fifo_get with a timeout and fiber that puts
	 * data on the fifo on time
	 */

	timeout = 5;
	orig_ticks = sys_tick_get();

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_put_timeout, (int)&fifo_timeout[0],
						timeout,
						FIBER_PRIORITY, 0);

	packet = nano_task_fifo_get(&fifo_timeout[0],
												(int)(timeout + 5));
	if (!packet) {
		TC_ERROR(" *** data put in time did not return valid pointer.\n");
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	put_scratch_packet(packet);

	if (!is_timeout_in_range(orig_ticks, timeout)) {
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	TC_PRINT("nano_task_fifo_get got fifo in time, as expected\n");

	/*
	 * test nano_task_fifo_get with TICKS_NONE and no data
	 * unavailable.
	 */

	if (nano_task_fifo_get(&fifo_timeout[0], TICKS_NONE)) {
		TC_ERROR("task with TICKS_NONE got data, but shouldn't have\n");
		return TC_FAIL;
	}

	TC_PRINT("task with TICKS_NONE did not get data, as expected\n");

	/*
	 * test nano_task_fifo_get with TICKS_NONE and some data
	 * available.
	 */

	scratch_packet = get_scratch_packet();
	nano_task_fifo_put(&fifo_timeout[0], scratch_packet);
	if (!nano_task_fifo_get(&fifo_timeout[0], TICKS_NONE)) {
		TC_ERROR("task with TICKS_NONE did not get available data\n");
		return TC_FAIL;
	}
	put_scratch_packet(scratch_packet);

	TC_PRINT("task with TICKS_NONE got available data, as expected\n");

	/*
	 * test nano_task_fifo_get with TICKS_UNLIMITED and the
	 * data available.
	 */

	TC_PRINT("Trying to take available data with TICKS_UNLIMITED:\n"
			 " will hang the test if it fails.\n");

	scratch_packet = get_scratch_packet();
	nano_task_fifo_put(&fifo_timeout[0], scratch_packet);
	if (!nano_task_fifo_get(&fifo_timeout[0], TICKS_UNLIMITED)) {
		TC_ERROR(" *** This will never be hit!!! .\n");
		return TC_FAIL;
	}
	put_scratch_packet(scratch_packet);

	TC_PRINT("task with TICKS_UNLIMITED got available data, as expected\n");

	/* test fiber with timeout of TICKS_NONE not getting data on empty fifo */

	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 0) {
		TC_ERROR(" *** fiber should not have obtained the data.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_NONE did not get data, as expected\n");

	/* test fiber with timeout of TICKS_NONE getting data when available */

	scratch_packet = get_scratch_packet();
	nano_task_fifo_put(&fifo_timeout[0], scratch_packet);
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);
	put_scratch_packet(scratch_packet);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 1) {
		TC_ERROR(" *** fiber should have obtained the data.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_NONE got available data, as expected\n");

	/* test fiber with TICKS_UNLIMITED timeout getting data when availalble */

	scratch_packet = get_scratch_packet();
	nano_task_fifo_put(&fifo_timeout[0], scratch_packet);
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_ticks_special_values,
						(int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0);
	put_scratch_packet(scratch_packet);

	if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
		TC_ERROR(" *** fiber should have run and filled the fifo.\n");
		return TC_FAIL;
	}

	if (reply_packet.reply != 1) {
		TC_ERROR(" *** fiber should have obtained the data.\n");
		return TC_FAIL;
	}

	TC_PRINT("fiber with TICKS_UNLIMITED got available data, as expected\n");

	/* test multiple fibers pending on the same fifo with different timeouts */

	test_data_size = ARRAY_SIZE(timeout_order_data);

	TC_PRINT("testing timeouts of %d fibers on same fifo\n", test_data_size);

	rv = test_multiple_fibers_pending(timeout_order_data, test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not time out in the right order\n");
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	/* test mult. fibers pending on different fifos with different timeouts */

	test_data_size = ARRAY_SIZE(timeout_order_data_mult_fifo);

	TC_PRINT("testing timeouts of %d fibers on different fifos\n",
				test_data_size);

	rv = test_multiple_fibers_pending(timeout_order_data_mult_fifo,
										test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not time out in the right order\n");
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	/*
	 * test multiple fibers 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);

	TC_PRINT("testing %d fibers timing out, but obtaining the data in time\n"
				"(except the last one, which times out)\n",
				test_data_size);

	rv = test_multiple_fibers_get_data(timeout_order_data, test_data_size);
	if (rv != TC_PASS) {
		TC_ERROR(" *** fibers did not get the data in the right order\n");
		TC_END_RESULT(TC_FAIL);
		return TC_FAIL;
	}

	TC_END_RESULT(TC_PASS);
	return TC_PASS;
}
