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

/**
 * @brief Workqueue Tests
 * @defgroup kernel_workqueue_tests Workqueue
 * @ingroup all_tests
 * @{
 * @}
 */

#include <ztest.h>
#include <irq_offload.h>

#define TIMEOUT 100
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#define NUM_OF_WORK 2

static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
static K_THREAD_STACK_DEFINE(user_tstack, STACK_SIZE);
static struct k_work_q workq;
static struct k_work_q user_workq;
static ZTEST_BMEM struct k_work work[NUM_OF_WORK];
static struct k_delayed_work new_work;
static struct k_delayed_work delayed_work[NUM_OF_WORK], delayed_work_sleepy;
static struct k_sem sync_sema;
static struct k_sem dummy_sema;
static struct k_thread *main_thread;

static void work_sleepy(struct k_work *w)
{
	k_sleep(TIMEOUT);
	k_sem_give(&sync_sema);
}

static void work_handler(struct k_work *w)
{
	/* Just to show an API call on this will succeed */
	k_sem_init(&dummy_sema, 0, 1);

	k_sem_give(&sync_sema);
}

static void new_work_handler(struct k_work *w)
{
	k_sem_give(&sync_sema);
}

static void twork_submit(void *data)
{
	struct k_work_q *work_q = (struct k_work_q *)data;

	for (int i = 0; i < NUM_OF_WORK; i++) {
		/**TESTPOINT: init via k_work_init*/
		k_work_init(&work[i], work_handler);
		/**TESTPOINT: check pending after work init*/
		zassert_false(k_work_pending(&work[i]), NULL);
		if (work_q) {
			/**TESTPOINT: work submit to queue*/
			zassert_false(k_work_submit_to_user_queue(work_q, &work[i]),
				      "failed to submit to queue");
		} else {
			/**TESTPOINT: work submit to system queue*/
			k_work_submit(&work[i]);
		}
	}
}

static void twork_submit_multipleq(void *data)
{
	struct k_work_q *work_q = (struct k_work_q *)data;

	/**TESTPOINT: init via k_work_init*/
	k_delayed_work_init(&new_work, new_work_handler);

	k_delayed_work_submit_to_queue(work_q, &new_work, TIMEOUT);

	zassert_equal(k_delayed_work_submit(&new_work, TIMEOUT),
		      -EADDRINUSE, NULL);

	k_sem_give(&sync_sema);
}

static void twork_resubmit(void *data)
{
	struct k_work_q *work_q = (struct k_work_q *)data;

	/**TESTPOINT: init via k_work_init*/
	k_delayed_work_init(&new_work, new_work_handler);

	k_delayed_work_submit_to_queue(work_q, &new_work, 0);

	/* This is done to test a neagtive case when k_delayed_work_cancel()
	 * fails in k_delayed_work_submit_to_queue API. Removing work from it
	 * queue make sure that k_delayed_work_cancel() fails when the Work is
	 * resubmitted.
	 */
	k_queue_remove(&(new_work.work_q->queue), &(new_work.work));

	zassert_equal(k_delayed_work_submit_to_queue(work_q, &new_work, 0),
		      -EINVAL, NULL);

	k_sem_give(&sync_sema);
}


static void tdelayed_work_submit(void *data)
{
	struct k_work_q *work_q = (struct k_work_q *)data;

	for (int i = 0; i < NUM_OF_WORK; i++) {
		/**TESTPOINT: init via k_delayed_work_init*/
		k_delayed_work_init(&delayed_work[i], work_handler);
		/**TESTPOINT: check pending after delayed work init*/
		zassert_false(k_work_pending((struct k_work *)&delayed_work[i]),
			      NULL);
		/**TESTPOINT: check remaining timeout before submit*/
		zassert_equal(k_delayed_work_remaining_get(&delayed_work[i]), 0,
			      NULL);
		if (work_q) {
			/**TESTPOINT: delayed work submit to queue*/
			zassert_true(k_delayed_work_submit_to_queue(work_q,
								    &delayed_work[i], TIMEOUT) == 0, NULL);
		} else {
			/**TESTPOINT: delayed work submit to system queue*/
			zassert_true(k_delayed_work_submit(&delayed_work[i],
							   TIMEOUT) == 0, NULL);
		}
		/**TESTPOINT: check remaining timeout after submit*/
		zassert_true(k_delayed_work_remaining_get(&delayed_work[i]) >=
			     TIMEOUT, NULL);
		/**TESTPOINT: check pending after delayed work submit*/
		zassert_true(k_work_pending((struct k_work *)&delayed_work[i])
			     == 0, NULL);
	}
}

static void tdelayed_work_cancel(void *data)
{
	struct k_work_q *work_q = (struct k_work_q *)data;
	int ret;

	k_delayed_work_init(&delayed_work_sleepy, work_sleepy);
	k_delayed_work_init(&delayed_work[0], work_handler);
	k_delayed_work_init(&delayed_work[1], work_handler);

	if (work_q) {
		ret = k_delayed_work_submit_to_queue(work_q,
						     &delayed_work_sleepy, TIMEOUT);
		ret |= k_delayed_work_submit_to_queue(work_q, &delayed_work[0],
						      TIMEOUT);
		ret |= k_delayed_work_submit_to_queue(work_q, &delayed_work[1],
						      TIMEOUT);
	} else {
		ret = k_delayed_work_submit(&delayed_work_sleepy, TIMEOUT);
		ret |= k_delayed_work_submit(&delayed_work[0], TIMEOUT);
		ret |= k_delayed_work_submit(&delayed_work[1], TIMEOUT);
	}
	/*
	 * t0: delayed submit three work items, all with delay=TIMEOUT
	 * >t0: cancel delayed_work[0], expected cancellation success
	 * >t0+TIMEOUT: handling delayed_work_sleepy, which do k_sleep TIMEOUT
	 *              pending delayed_work[1], check pending flag, expected 1
	 *              cancel delayed_work[1], expected 0
	 * >t0+2*TIMEOUT: delayed_work_sleepy completed
	 *                delayed_work[1] completed
	 *                cancel delayed_work_sleepy, expected 0
	 */
	zassert_true(ret == 0, NULL);
	/**TESTPOINT: delayed work cancel when countdown*/
	ret = k_delayed_work_cancel(&delayed_work[0]);
	zassert_true(ret == 0, NULL);
	/**TESTPOINT: check pending after delayed work cancel*/
	zassert_false(k_work_pending((struct k_work *)&delayed_work[0]), NULL);
	if (!k_is_in_isr()) {
		/*wait for handling work_sleepy*/
		k_sleep(TIMEOUT);
		/**TESTPOINT: check pending when work pending*/
		zassert_true(k_work_pending((struct k_work *)&delayed_work[1]),
			     NULL);
		/**TESTPOINT: delayed work cancel when pending*/
		ret = k_delayed_work_cancel(&delayed_work[1]);
		zassert_equal(ret, 0, NULL);
		k_sem_give(&sync_sema);
		/*wait for completed work_sleepy and delayed_work[1]*/
		k_sleep(TIMEOUT);
		/**TESTPOINT: check pending when work completed*/
		zassert_false(k_work_pending(
				      (struct k_work *)&delayed_work_sleepy), NULL);
		/**TESTPOINT: delayed work cancel when completed*/
		ret = k_delayed_work_cancel(&delayed_work_sleepy);
		zassert_equal(ret, 0, NULL);
	}
	/*work items not cancelled: delayed_work[1], delayed_work_sleepy*/
}

/*test cases*/
/**
 * @brief Test work queue start before submit
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_q_start()
 */
void test_workq_start_before_submit(void)
{
	k_work_q_start(&workq, tstack, STACK_SIZE,
		       CONFIG_MAIN_THREAD_PRIORITY);
}

/**
 * @brief Test user mode work queue start before submit
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_q_user_start()
 */
void test_user_workq_start_before_submit(void)
{
	k_work_q_user_start(&user_workq, user_tstack, STACK_SIZE,
			    CONFIG_MAIN_THREAD_PRIORITY);
}

/**
 * @brief Setup object permissions before test_user_workq_granted_access()
 *
 * @ingroup kernel_workqueue_tests
 */
void test_user_workq_granted_access_setup(void)
{
	/* Subsequent test cases will have access to the dummy_sema,
	 * but not the user workqueue since it already started.
	 */
	k_object_access_grant(&dummy_sema, main_thread);
}

/**
 * @brief Test user mode grant workqueue permissions
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_q_object_access_grant()
 */
void test_user_workq_granted_access(void)
{
	k_object_access_grant(&dummy_sema, &user_workq.thread);
}

/**
 * @brief Test work submission to work queue
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(),
 * k_work_submit()
 */
void test_work_submit_to_queue_thread(void)
{
	k_sem_reset(&sync_sema);
	twork_submit(&workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test work submission to work queue (user mode)
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(),
 * k_work_submit()
 */
void test_user_work_submit_to_queue_thread(void)
{
	k_sem_reset(&sync_sema);
	twork_submit(&user_workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test submission of work to multiple queues
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_init(), k_delayed_work_submit_to_queue(),
 * k_delayed_work_submit()
 */
void test_work_submit_to_multipleq(void)
{
	k_sem_reset(&sync_sema);
	twork_submit_multipleq(&workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test work queue resubmission
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_queue_remove(), k_delayed_work_init(),
 * k_delayed_work_submit_to_queue()
 */
void test_work_resubmit_to_queue(void)
{
	k_sem_reset(&sync_sema);
	twork_resubmit(&workq);
	k_sem_take(&sync_sema, K_FOREVER);
}

/**
 * @brief Test work submission to queue from ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), k_work_submit()
 */
void test_work_submit_to_queue_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(twork_submit, (void *)&workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test work submission to queue
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), k_work_submit()
 */
void test_work_submit_thread(void)
{
	k_sem_reset(&sync_sema);
	twork_submit(NULL);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test work submission from ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), k_work_submit()
 */
void test_work_submit_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(twork_submit, NULL);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work submission to queue
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_init(), k_work_pending(),
 * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(),
 * k_delayed_work_submit()
 */
void test_delayed_work_submit_to_queue_thread(void)
{
	k_sem_reset(&sync_sema);
	tdelayed_work_submit(&workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work submission to queue in ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_init(), k_work_pending(),
 * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(),
 * k_delayed_work_submit()
 */
void test_delayed_work_submit_to_queue_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(tdelayed_work_submit, (void *)&workq);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work submission
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_init(), k_work_pending(),
 * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(),
 * k_delayed_work_submit()
 */
void test_delayed_work_submit_thread(void)
{
	k_sem_reset(&sync_sema);
	tdelayed_work_submit(NULL);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work submission from ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_init(), k_work_pending(),
 * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(),
 * k_delayed_work_submit()
 */
void test_delayed_work_submit_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(tdelayed_work_submit, NULL);
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work cancel from work queue
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_cancel(), k_work_pending()
 */
void test_delayed_work_cancel_from_queue_thread(void)
{
	k_sem_reset(&sync_sema);
	tdelayed_work_cancel(&workq);
	/*wait for work items that could not be cancelled*/
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work cancel from work queue from ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_cancel(), k_work_pending()
 */
void test_delayed_work_cancel_from_queue_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(tdelayed_work_cancel, &workq);
	/*wait for work items that could not be cancelled*/
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work cancel
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_cancel(), k_work_pending()
 */
void test_delayed_work_cancel_thread(void)
{
	k_sem_reset(&sync_sema);
	tdelayed_work_cancel(NULL);
	/*wait for work items that could not be cancelled*/
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}

/**
 * @brief Test delayed work cancel from ISR context
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_delayed_work_cancel(), k_work_pending()
 */
void test_delayed_work_cancel_isr(void)
{
	k_sem_reset(&sync_sema);
	irq_offload(tdelayed_work_cancel, NULL);
	/*wait for work items that could not be cancelled*/
	for (int i = 0; i < NUM_OF_WORK; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}
}


void test_main(void)
{
	main_thread = k_current_get();
	k_thread_access_grant(main_thread, &sync_sema, &user_workq.thread,
			      &user_workq.queue,
			      &user_tstack);
	k_sem_init(&sync_sema, 0, NUM_OF_WORK);
	k_thread_system_pool_assign(k_current_get());

	ztest_test_suite(workqueue_api,
			 /* Do not disturb the ordering of these test cases */
			 ztest_unit_test(test_workq_start_before_submit),
			 ztest_user_unit_test(test_user_workq_start_before_submit),
			 ztest_unit_test(test_user_workq_granted_access_setup),
			 ztest_user_unit_test(test_user_workq_granted_access),
			 /* End order-important tests */

			 ztest_unit_test(test_work_submit_to_multipleq),
			 ztest_unit_test(test_work_resubmit_to_queue),
			 ztest_unit_test(test_work_submit_to_queue_thread),
			 ztest_unit_test(test_work_submit_to_queue_isr),
			 ztest_unit_test(test_work_submit_thread),
			 ztest_unit_test(test_work_submit_isr),
			 ztest_user_unit_test(test_user_work_submit_to_queue_thread),
			 ztest_unit_test(test_delayed_work_submit_to_queue_thread),
			 ztest_unit_test(test_delayed_work_submit_to_queue_isr),
			 ztest_unit_test(test_delayed_work_submit_thread),
			 ztest_unit_test(test_delayed_work_submit_isr),
			 ztest_unit_test(test_delayed_work_cancel_from_queue_thread),
			 ztest_unit_test(test_delayed_work_cancel_from_queue_isr),
			 ztest_unit_test(test_delayed_work_cancel_thread),
			 ztest_unit_test(test_delayed_work_cancel_isr));
	ztest_run_test_suite(workqueue_api);
}
