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

#include "test_queue.h"

#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#define LIST_LEN 2
/**TESTPOINT: init via K_QUEUE_DEFINE*/
K_QUEUE_DEFINE(kqueue);

K_HEAP_DEFINE(mem_pool_fail, 8 + 128);
K_HEAP_DEFINE(mem_pool_pass, 64 * 4 + 128);

struct k_queue queue;
static qdata_t data[LIST_LEN];
static qdata_t data_p[LIST_LEN];
static qdata_t data_l[LIST_LEN];
static qdata_t data_sl[LIST_LEN];

static qdata_t *data_append;
static qdata_t *data_prepend;

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

static void tqueue_append(struct k_queue *pqueue)
{
	k_queue_insert(pqueue, k_queue_peek_tail(pqueue),
		       (void *)&data[0]);

	for (int i = 1; i < LIST_LEN; i++) {
		/**TESTPOINT: queue append */
		k_queue_append(pqueue, (void *)&data[i]);
	}

	for (int i = LIST_LEN - 1; i >= 0; i--) {
		/**TESTPOINT: queue prepend */
		k_queue_prepend(pqueue, (void *)&data_p[i]);
	}

	/**TESTPOINT: queue append list*/
	static qdata_t *head = &data_l[0], *tail = &data_l[LIST_LEN - 1];

	head->snode.next = (sys_snode_t *)tail;
	tail->snode.next = NULL;
	k_queue_append_list(pqueue, (uint32_t *)head, (uint32_t *)tail);

	/**TESTPOINT: queue merge slist*/
	sys_slist_t slist;

	sys_slist_init(&slist);
	sys_slist_append(&slist, (sys_snode_t *)&(data_sl[0].snode));
	sys_slist_append(&slist, (sys_snode_t *)&(data_sl[1].snode));
	k_queue_merge_slist(pqueue, &slist);
}

static void tqueue_get(struct k_queue *pqueue)
{
	void *rx_data;

	/*get queue data from "queue_prepend"*/
	for (int i = 0; i < LIST_LEN; i++) {
		/**TESTPOINT: queue get*/
		rx_data = k_queue_get(pqueue, K_NO_WAIT);
		zassert_equal(rx_data, (void *)&data_p[i], NULL);
	}
	/*get queue data from "queue_append"*/
	for (int i = 0; i < LIST_LEN; i++) {
		/**TESTPOINT: queue get*/
		rx_data = k_queue_get(pqueue, K_NO_WAIT);
		zassert_equal(rx_data, (void *)&data[i], NULL);
	}
	/*get queue data from "queue_append_list"*/
	for (int i = 0; i < LIST_LEN; i++) {
		rx_data = k_queue_get(pqueue, K_NO_WAIT);
		zassert_equal(rx_data, (void *)&data_l[i], NULL);
	}
	/*get queue data from "queue_merge_slist"*/
	for (int i = 0; i < LIST_LEN; i++) {
		rx_data = k_queue_get(pqueue, K_NO_WAIT);
		zassert_equal(rx_data, (void *)&data_sl[i], NULL);
	}
}

/*entry of contexts*/
static void tIsr_entry_append(const void *p)
{
	tqueue_append((struct k_queue *)p);
}

static void tIsr_entry_get(const void *p)
{
	tqueue_get((struct k_queue *)p);
}

static void tThread_entry(void *p1, void *p2, void *p3)
{
	tqueue_get((struct k_queue *)p1);
	k_sem_give(&end_sema);
}

static void tqueue_thread_thread(struct k_queue *pqueue)
{
	k_sem_init(&end_sema, 0, 1);
	/**TESTPOINT: thread-thread data passing via queue*/
	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      tThread_entry, pqueue, NULL, NULL,
				      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
	tqueue_append(pqueue);
	k_sem_take(&end_sema, K_FOREVER);
	k_thread_abort(tid);
}

static void tqueue_thread_isr(struct k_queue *pqueue)
{
	k_sem_init(&end_sema, 0, 1);
	/**TESTPOINT: thread-isr data passing via queue*/
	irq_offload(tIsr_entry_append, (const void *)pqueue);
	tqueue_get(pqueue);
}

static void tqueue_isr_thread(struct k_queue *pqueue)
{
	k_sem_init(&end_sema, 0, 1);
	/**TESTPOINT: isr-thread data passing via queue*/
	tqueue_append(pqueue);
	irq_offload(tIsr_entry_get, (const void *)pqueue);
}

/*test cases*/
/**
 * @brief Verify data passing between threads using queue
 *
 * @details Static define and Dynamic define queues,
 * Then initialize them.
 * Create a new thread to wait for reading data.
 * Current thread will append item into queue.
 * Verify if rx_data is equal insert-data address.
 * Verify queue can be define at compile time.
 *
 * @ingroup kernel_queue_tests
 *
 * @see k_queue_init(), k_queue_insert(), k_queue_append()
 * K_THREAD_STACK_DEFINE()
 */
void test_queue_thread2thread(void)
{
	/**TESTPOINT: init via k_queue_init*/
	k_queue_init(&queue);
	tqueue_thread_thread(&queue);

	/**TESTPOINT: test K_QUEUE_DEFINEed queue*/
	tqueue_thread_thread(&kqueue);
}

/**
 * @brief Verify data passing between thread and ISR
 *
 * @details Create a new ISR to insert data
 * And current thread is used for getting data
 * Verify if the rx_data is equal insert-data address.
 * If the received data address is the same as
 * the created array, prove that the queue data structures
 * are stored within the provided data items.
 *
 * @ingroup kernel_queue_tests
 *
 * @see k_queue_init(), k_queue_insert(), k_queue_append()
 */
void test_queue_thread2isr(void)
{
	/**TESTPOINT: init via k_queue_init*/
	k_queue_init(&queue);
	tqueue_thread_isr(&queue);

	/**TESTPOINT: test K_QUEUE_DEFINEed queue*/
	tqueue_thread_isr(&kqueue);
}

/**
 * @brief Verify data passing between ISR and thread
 *
 * @details Create a new ISR and ready for getting data
 * And current thread is used for inserting data
 * Verify if the rx_data is equal insert-data address.
 *
 * @ingroup kernel_queue_tests
 *
 * @see k_queue_init(), k_queue_insert(), k_queue_get(),
 * k_queue_append(), k_queue_remove()
 */
void test_queue_isr2thread(void)
{
	/**TESTPOINT: test k_queue_init queue*/
	k_queue_init(&queue);
	tqueue_isr_thread(&queue);

	/**TESTPOINT: test K_QUEUE_DEFINE queue*/
	tqueue_isr_thread(&kqueue);
}

static void tThread_get(void *p1, void *p2, void *p3)
{
	zassert_true(k_queue_get((struct k_queue *)p1, K_FOREVER) != NULL,
		     NULL);
	k_sem_give(&end_sema);
}

static void tqueue_get_2threads(struct k_queue *pqueue)
{
	k_sem_init(&end_sema, 0, 1);
	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      tThread_get, pqueue, NULL, NULL,
				      K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	k_tid_t tid1 = k_thread_create(&tdata1, tstack1, STACK_SIZE,
				       tThread_get, pqueue, NULL, NULL,
				       K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

	/* Wait threads to initialize */
	k_sleep(K_MSEC(10));

	k_queue_append(pqueue, (void *)&data[0]);
	k_queue_append(pqueue, (void *)&data[1]);
	/* Wait threads to finalize */
	k_sem_take(&end_sema, K_FOREVER);
	k_sem_take(&end_sema, K_FOREVER);

	k_thread_abort(tid);
	k_thread_abort(tid1);
}

/**
 * @brief Verify k_queue_get()
 * @ingroup kernel_queue_tests
 * @see k_queue_init(), k_queue_get(),
 * k_queue_append(), k_queue_alloc_prepend()
 */
void test_queue_get_2threads(void)
{
	/**TESTPOINT: test k_queue_init queue*/
	k_queue_init(&queue);

	tqueue_get_2threads(&queue);
}

static void tqueue_alloc(struct k_queue *pqueue)
{
	k_thread_heap_assign(k_current_get(), NULL);

	/* Alloc append without resource pool */
	k_queue_alloc_append(pqueue, (void *)&data_append);

	/* Insertion fails and alloc returns NOMEM */
	zassert_false(k_queue_remove(pqueue, &data_append), NULL);

	/* Assign resource pool of lower size */
	k_thread_heap_assign(k_current_get(), &mem_pool_fail);

	/* Prepend to the queue, but fails because of
	 * insufficient memory
	 */
	k_queue_alloc_prepend(pqueue, (void *)&data_prepend);

	zassert_false(k_queue_remove(pqueue, &data_prepend), NULL);

	/* No element must be present in the queue, as all
	 * operations failed
	 */
	zassert_true(k_queue_is_empty(pqueue), NULL);

	/* Assign resource pool of sufficient size */
	k_thread_heap_assign(k_current_get(), &mem_pool_pass);

	zassert_false(k_queue_alloc_prepend(pqueue, (void *)&data_prepend),
		      NULL);

	/* Now queue shouldn't be empty */
	zassert_false(k_queue_is_empty(pqueue), NULL);

	zassert_true(k_queue_get(pqueue, K_FOREVER) != NULL,
		     NULL);
}

/**
 * @brief Test queue alloc append and prepend
 * @ingroup kernel_queue_tests
 * @see k_queue_alloc_append(), k_queue_alloc_prepend(),
 * z_thread_resource_pool_assign(), k_queue_is_empty(),
 * k_queue_get(), k_queue_remove()
 */
void test_queue_alloc(void)
{
	/* The mem_pool_fail pool is supposed to be too small to
	 * succeed any allocations, but in fact with the heap backend
	 * there's some base minimal memory in there that can be used.
	 * Make sure it's really truly full.
	 */
	while (k_heap_alloc(&mem_pool_fail, 1, K_NO_WAIT) != NULL) {
	}

	k_queue_init(&queue);

	tqueue_alloc(&queue);
}


/* Does nothing but read items out of the queue and verify that they
 * are non-null.  Two such threads will be created.
 */
static void queue_poll_race_consume(void *p1, void *p2, void *p3)
{
	struct k_queue *q = p1;
	int *count = p2;

	while (true) {
		zassert_true(k_queue_get(q, K_FOREVER) != NULL, NULL);
		*count += 1;
	}
}

/* There was a historical race in the queue internals when CONFIG_POLL
 * was enabled -- it was possible to wake up a lower priority thread
 * with an insert but then steal it with a higher priority thread
 * before it got a chance to run, and the lower priority thread would
 * then return NULL before its timeout expired.
 */
void test_queue_poll_race(void)
{
	int prio = k_thread_priority_get(k_current_get());
	int mid_count = 0, low_count = 0;

	k_queue_init(&queue);

	k_thread_create(&tdata, tstack, STACK_SIZE,
			queue_poll_race_consume,
			&queue, &mid_count, NULL,
			prio + 1, 0, K_NO_WAIT);

	k_thread_create(&tdata1, tstack1, STACK_SIZE,
			queue_poll_race_consume,
			&queue, &low_count, NULL,
			prio + 2, 0, K_NO_WAIT);

	/* Let them initialize and block */
	k_sleep(K_TICKS(2));

	/* Insert two items.  This will wake up both threads, but the
	 * higher priority thread (tdata1) might (if CONFIG_POLL)
	 * consume both.  The lower priority thread should stay
	 * asleep.
	 */
	k_queue_append(&queue, &data[0]);
	k_queue_append(&queue, &data[1]);

	zassert_true(low_count == 0, NULL);
	zassert_true(mid_count == 0, NULL);

	k_sleep(K_TICKS(2));

	zassert_true(low_count + mid_count == 2, NULL);

	k_thread_abort(&tdata);
	k_thread_abort(&tdata1);
}

/**
 * @brief Verify that multiple queues can be defined
 * simultaneously
 *
 * @details define multiple queues to verify
 * they can work.
 *
 * @ingroup kernel_queue_tests
 *
 * @see k_queue_init()
 */
#define QUEUE_NUM 10
void test_multiple_queues(void)
{
	/*define multiple queues*/
	static struct k_queue queues[QUEUE_NUM];

	for (int i = 0; i < QUEUE_NUM; i++) {
		k_queue_init(&queues[i]);

		/*Indicating that they are working*/
		tqueue_append(&queues[i]);
		tqueue_get(&queues[i]);
	}
}

void user_access_queue_private_data(void *p1, void *p2, void *p3)
{
	ztest_set_fault_valid(true);
	/* try to access to private kernel data, will happen kernel oops */
	k_queue_is_empty(&queue);
}

/**
 * @brief Test access kernel object with private data using system call
 *
 * @details
 * - When defining system calls, it is very important to ensure that
 *   access to the API’s private data is done exclusively through system call
 *   interfaces. Private kernel data should never be made available to user mode
 *   threads directly. For example, the k_queue APIs were intentionally not made
 *   available as they store bookkeeping information about the queue directly
 *   in the queue buffers which are visible from user mode.
 * - Current test makes user thread try to access private kernel data within
 *   their associated data structures. Kernel will track that system call
 *   access to these object with the kernel object permission system.
 *   Current user thread doesn't have permission on it, trying to access
 *   &pqueue kernel object will happen kernel oops, because current user
 *   thread doesn't have permission on k_queue object with private kernel data.
 *
 * @ingroup kernel_memprotect_tests
 */
void test_access_kernel_obj_with_priv_data(void)
{
	k_queue_init(&queue);
	k_queue_insert(&queue, k_queue_peek_tail(&queue), (void *)&data[0]);
	k_thread_create(&tdata, tstack, STACK_SIZE, user_access_queue_private_data,
					NULL, NULL, NULL, 0, K_USER, K_NO_WAIT);
	k_thread_join(&tdata, K_FOREVER);
}
