/*
 * Copyright (c) 2016 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <tc_util.h>
#include <ztest.h>
#include <zephyr/kernel.h>
#include <zephyr/kernel_structs.h>
#include <stdbool.h>

#define  NUM_SECONDS(x)      ((x) * 1000)
#define  HALF_SECOND                (500)
#define  THIRD_SECOND               (333)
#define  FOURTH_SECOND              (250)

#define COOP_STACKSIZE   (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define PREEM_STACKSIZE  (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)

#define FIFO_TEST_START       10
#define FIFO_TEST_END         20

#define SEM_TEST_START        30
#define SEM_TEST_END          40

#define LIFO_TEST_START       50
#define LIFO_TEST_END         60

#define NON_NULL_PTR          ((void *)0x12345678)

#ifdef CONFIG_COVERAGE
#define OFFLOAD_WORKQUEUE_STACK_SIZE 4096
#else
#define OFFLOAD_WORKQUEUE_STACK_SIZE 1024
#endif

#define OFFLOAD_WORKQUEUE_PRIORITY	(-1)
static struct k_work_q offload_work_q;
static K_THREAD_STACK_DEFINE(offload_work_q_stack,
			     OFFLOAD_WORKQUEUE_STACK_SIZE);

struct fifo_data {
	intptr_t reserved;
	uint32_t data;
};

struct lifo_data {
	intptr_t reserved;
	uint32_t data;
};

struct offload_work {
	struct k_work work_item;
	struct k_sem *sem;
};

static K_THREAD_STACK_ARRAY_DEFINE(coop_stack, 2, COOP_STACKSIZE);
static struct k_thread coop_thread[2];

static struct k_fifo fifo;
static struct k_lifo lifo;
static struct k_timer timer;

static struct k_sem start_test_sem;
static struct k_sem sync_test_sem;
static struct k_sem end_test_sem;

struct fifo_data fifo_test_data[4] = {
	{ 0, FIFO_TEST_END + 1 }, { 0, FIFO_TEST_END + 2 },
	{ 0, FIFO_TEST_END + 3 }, { 0, FIFO_TEST_END + 4 }
};

struct lifo_data lifo_test_data[4] = {
	{ 0, LIFO_TEST_END + 1 }, { 0, LIFO_TEST_END + 2 },
	{ 0, LIFO_TEST_END + 3 }, { 0, LIFO_TEST_END + 4 }
};

static uint32_t timer_start_tick;
static uint32_t timer_end_tick;
static void *timer_data;

static int __noinit coop_high_state;
static int __noinit coop_low_state;
static int __noinit task_high_state;
static int __noinit task_low_state;

static int __noinit counter;

static inline void *my_fifo_get(struct k_fifo *fifo, int32_t timeout)
{
	return k_fifo_get(fifo, K_MSEC(timeout));
}

static inline void *my_lifo_get(struct k_lifo *lifo, int32_t timeout)
{
	return k_lifo_get(lifo, K_MSEC(timeout));
}

static int increment_counter(void)
{
	int tmp;
	unsigned int key = irq_lock();

	tmp = ++counter;
	irq_unlock(key);

	return tmp;
}

static void sync_threads(struct k_work *work)
{
	struct offload_work *offload =
		CONTAINER_OF(work, struct offload_work, work_item);

	k_sem_give(offload->sem);
	k_sem_give(offload->sem);
	k_sem_give(offload->sem);
	k_sem_give(offload->sem);

}

static void fifo_tests(int32_t timeout, volatile int *state,
		       void *(*get)(struct k_fifo *, int32_t),
		       int (*sem_take)(struct k_sem *, k_timeout_t))
{
	struct fifo_data *data;

	sem_take(&start_test_sem, K_FOREVER);

	*state = FIFO_TEST_START;
	/* Expect this to time out */
	data = get(&fifo, timeout);
	if (data != NULL) {
		TC_ERROR("**** Unexpected data on FIFO get\n");
		return;
	}
	*state = increment_counter();

	/* Sync up fifo test threads */
	sem_take(&sync_test_sem, K_FOREVER);

	/* Expect this to receive data from the fifo */
	*state = FIFO_TEST_END;
	data = get(&fifo, timeout);
	if (data == NULL) {
		TC_ERROR("**** No data on FIFO get\n");
		return;
	}
	*state = increment_counter();

	if (data->data != *state) {
		TC_ERROR("**** Got FIFO data %d, not %d (%d)\n",
			 data->data, *state, timeout);
		return;
	}

	sem_take(&end_test_sem, K_FOREVER);
}

static void lifo_tests(int32_t timeout, volatile int *state,
		       void *(*get)(struct k_lifo *, int32_t),
		       int (*sem_take)(struct k_sem *, k_timeout_t))
{
	struct lifo_data *data;

	sem_take(&start_test_sem, K_FOREVER);

	*state = LIFO_TEST_START;
	/* Expect this to time out */
	data = get(&lifo, timeout);
	if (data != NULL) {
		TC_ERROR("**** Unexpected data on LIFO get\n");
		return;
	}
	*state = increment_counter();

	/* Sync up all threads */
	sem_take(&sync_test_sem, K_FOREVER);

	/* Expect this to receive data from the lifo */
	*state = LIFO_TEST_END;
	data = get(&lifo, timeout);
	if (data == NULL) {
		TC_ERROR("**** No data on LIFO get\n");
		return;
	}
	*state = increment_counter();

	if (data->data != *state) {
		TC_ERROR("**** Got LIFO data %d, not %d (%d)\n",
			 data->data, *state, timeout);
		return;
	}

	sem_take(&end_test_sem, K_FOREVER);
}

static void timer_tests(void)
{
	k_sem_take(&start_test_sem, K_FOREVER);

	timer_start_tick = k_uptime_get_32();

	k_timer_start(&timer, K_SECONDS(1), K_NO_WAIT);

	if (k_timer_status_sync(&timer)) {
		timer_data = timer.user_data;
	}

	timer_end_tick = k_uptime_get_32();

	k_sem_take(&end_test_sem, K_FOREVER);
}

static void coop_high(void *arg1, void *arg2, void *arg3)
{
	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	fifo_tests(NUM_SECONDS(1), &coop_high_state, my_fifo_get, k_sem_take);

	lifo_tests(NUM_SECONDS(1), &coop_high_state, my_lifo_get, k_sem_take);
}

static void coop_low(void *arg1, void *arg2, void *arg3)
{
	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	fifo_tests(HALF_SECOND, &coop_low_state, my_fifo_get, k_sem_take);

	lifo_tests(HALF_SECOND, &coop_low_state, my_lifo_get, k_sem_take);
}

void task_high(void)
{
	k_fifo_init(&fifo);
	k_lifo_init(&lifo);

	k_timer_init(&timer, NULL, NULL);
	timer.user_data = NON_NULL_PTR;

	k_sem_init(&start_test_sem, 0, UINT_MAX);
	k_sem_init(&sync_test_sem, 0, UINT_MAX);
	k_sem_init(&end_test_sem, 0, UINT_MAX);

	k_work_queue_start(&offload_work_q,
		       offload_work_q_stack,
		       K_THREAD_STACK_SIZEOF(offload_work_q_stack),
		       OFFLOAD_WORKQUEUE_PRIORITY, NULL);

	counter = SEM_TEST_START;

	k_thread_create(&coop_thread[0], coop_stack[0], COOP_STACKSIZE,
			coop_high, NULL, NULL, NULL, K_PRIO_COOP(3), 0,
			K_NO_WAIT);

	k_thread_create(&coop_thread[1], coop_stack[1], COOP_STACKSIZE,
			coop_low, NULL, NULL, NULL, K_PRIO_COOP(7), 0,
			K_NO_WAIT);

	counter = FIFO_TEST_START;
	fifo_tests(THIRD_SECOND, &task_high_state, my_fifo_get, k_sem_take);

	counter = LIFO_TEST_START;
	lifo_tests(THIRD_SECOND, &task_high_state, my_lifo_get, k_sem_take);

	timer_tests();
}

void task_low(void)
{
	fifo_tests(FOURTH_SECOND, &task_low_state, my_fifo_get, k_sem_take);

	lifo_tests(FOURTH_SECOND, &task_low_state, my_lifo_get, k_sem_take);
}

/**
 * @brief Test pending
 *
 * @defgroup kernel_pending_tests Pending tests
 *
 * @ingroup all_tests
 *
 * @{
 */

/**
 * @brief Test pending of workq, fifo and lifo
 *
 * @see k_sleep(), K_THREAD_DEFINE()
 */
void test_pending_fifo(void)
{
	/*
	 * Main thread(test_main) priority was 9 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(k_current_get(), 9);

	struct offload_work offload1 = {0};

	k_work_init(&offload1.work_item, sync_threads);
	offload1.sem = &start_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload1.work_item);

	/*
	 * Verify that preemptible threads 'task_high' and 'task_low' do not
	 * busy-wait. If they are not busy-waiting, then they must be pending.
	 */

	TC_PRINT("Testing preemptible threads block on fifos ...\n");
	zassert_false((coop_high_state != FIFO_TEST_START) ||
		      (coop_low_state != FIFO_TEST_START) ||
		      (task_high_state != FIFO_TEST_START) ||
		      (task_low_state != FIFO_TEST_START), NULL);

	/* Give waiting threads time to time-out */
	k_sleep(K_SECONDS(2));

	/*
	 * Verify that the cooperative and preemptible threads timed-out in
	 * the correct order.
	 */

	TC_PRINT("Testing fifos time-out in correct order ...\n");
	zassert_false((task_low_state != FIFO_TEST_START + 1) ||
		      (task_high_state != FIFO_TEST_START + 2) ||
		      (coop_low_state != FIFO_TEST_START + 3) ||
		      (coop_high_state != FIFO_TEST_START + 4),
		      "**** Threads timed-out in unexpected order");

	counter = FIFO_TEST_END;

	k_work_init(&offload1.work_item, sync_threads);
	offload1.sem = &sync_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload1.work_item);

	/*
	 * Two cooperative and two preemptible threads should be waiting on
	 * the FIFO
	 */

	/* Add data to the FIFO */
	TC_PRINT("Testing  fifos delivered data correctly ...\n");
	k_fifo_put(&fifo, &fifo_test_data[0]);
	k_fifo_put(&fifo, &fifo_test_data[1]);
	k_fifo_put(&fifo, &fifo_test_data[2]);
	k_fifo_put(&fifo, &fifo_test_data[3]);

	zassert_false((coop_high_state != FIFO_TEST_END + 1) ||
		      (coop_low_state != FIFO_TEST_END + 2) ||
		      (task_high_state != FIFO_TEST_END + 3) ||
		      (task_low_state != FIFO_TEST_END + 4),
		      "**** Unexpected delivery order");
}


void test_pending_lifo(void)
{
	/*
	 * Main thread(test_main) priority was 9 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(k_current_get(), 9);

	struct offload_work offload1 = {0};
	struct offload_work offload2 = {0};

	k_work_init(&offload1.work_item, sync_threads);
	offload1.sem = &end_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload1.work_item);

	k_work_init(&offload2.work_item, sync_threads);
	offload2.sem = &start_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload2.work_item);

	/*
	 * Verify that cooperative threads 'task_high' and 'task_low' do not
	 * busy-wait. If they are not busy-waiting, then they must be pending.
	 */

	TC_PRINT("Testing preemptible threads block on lifos ...\n");
	zassert_false((coop_high_state != LIFO_TEST_START) ||
		      (coop_low_state != LIFO_TEST_START) ||
		      (task_high_state != LIFO_TEST_START) ||
		      (task_low_state != LIFO_TEST_START), NULL);

	/* Give waiting threads time to time-out */
	k_sleep(K_SECONDS(2));

	TC_PRINT("Testing lifos time-out in correct order ...\n");
	zassert_false((task_low_state != LIFO_TEST_START + 1) ||
		      (task_high_state != LIFO_TEST_START + 2) ||
		      (coop_low_state != LIFO_TEST_START + 3) ||
		      (coop_high_state != LIFO_TEST_START + 4),
		      "**** Threads timed-out in unexpected order");

	counter = LIFO_TEST_END;

	k_work_init(&offload1.work_item, sync_threads);
	offload1.sem = &sync_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload1.work_item);

	/*
	 * Two cooperative threads and two preemptive threads should
	 * be waiting on the LIFO
	 */

	/* Add data to the LIFO */
	k_lifo_put(&lifo, &lifo_test_data[0]);
	k_lifo_put(&lifo, &lifo_test_data[1]);
	k_lifo_put(&lifo, &lifo_test_data[2]);
	k_lifo_put(&lifo, &lifo_test_data[3]);

	TC_PRINT("Testing lifos delivered data correctly ...\n");
	zassert_false((coop_high_state != LIFO_TEST_END + 1) ||
		      (coop_low_state != LIFO_TEST_END + 2) ||
		      (task_high_state != LIFO_TEST_END + 3) ||
		      (task_low_state != LIFO_TEST_END + 4),
		      "**** Unexpected timeout order");

}

void test_pending_timer(void)
{
	/*
	 * Main thread(test_main) priority was 9 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(k_current_get(), 9);

	struct offload_work offload2 = {0};

	k_work_init(&offload2.work_item, sync_threads);
	offload2.sem = &end_test_sem;
	k_work_submit_to_queue(&offload_work_q, &offload2.work_item);

	timer_end_tick = 0U;
	k_sem_give(&start_test_sem);    /* start timer tests */

	/*
	 * NOTE: The timer test is running in the context of high_task().
	 * Scheduling is expected to yield to high_task().  If high_task()
	 * does not pend as expected, then timer_end_tick will be non-zero.
	 */

	TC_PRINT("Testing preemptible thread waiting on timer ...\n");
	zassert_equal(timer_end_tick, 0, "Task did not pend on timer");

	/* Let the timer expire */
	k_sleep(K_SECONDS(2));

	zassert_false((timer_end_tick < timer_start_tick + NUM_SECONDS(1)),
			"Task waiting on timer error");

	zassert_equal(timer_data, NON_NULL_PTR,
				"Incorrect data from timer");

	k_sem_give(&end_test_sem);
}

/**
 * @}
 */
void test_main(void)
{
	ztest_test_suite(pend,
			ztest_1cpu_unit_test(test_pending_fifo),
			ztest_1cpu_unit_test(test_pending_lifo),
			ztest_1cpu_unit_test(test_pending_timer)
			);
	ztest_run_test_suite(pend);
}

K_THREAD_DEFINE(TASK_LOW, PREEM_STACKSIZE, task_low, NULL, NULL, NULL,
		7, 0, 0);

K_THREAD_DEFINE(TASK_HIGH, PREEM_STACKSIZE, task_high, NULL, NULL, NULL,
		5, 0, 0);
