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

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

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

#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define NUM_OF_WORK 2
#define SYNC_SEM_INIT_VAL (0U)

static K_THREAD_STACK_DEFINE(user_tstack, STACK_SIZE);
static struct k_work_user_q user_workq;
static ZTEST_BMEM struct k_work_user work[NUM_OF_WORK];
static struct k_sem sync_sema;
static struct k_sem dummy_sema;
static struct k_thread *main_thread;

/**
 * @brief Common function using like a handler for workqueue tests
 * API call in it means successful execution of that function
 *
 * @param unused of type k_work to make handler function accepted
 * by k_work_init
 */
static void common_work_handler(struct k_work_user *unused)
{
	k_sem_give(&sync_sema);
}

static void test_k_work_user_init(void)
{
	K_WORK_USER_DEFINE(local, common_work_handler);
	zassert_equal(local.handler, common_work_handler);
	zassert_equal(local.flags, 0);
}

/**
 * @brief Test k_work_user_submit_to_queue API
 *
 * @details Function k_work_user_submit_to_queue() will return
 * -EBUSY: if the work item was already in some workqueue and
 * -ENOMEM: if no memory for thread resource pool allocation.
 * Create two situation to meet the error return value.
 *
 * @see k_work_user_submit_to_queue()
 * @ingroup kernel_workqueue_tests
 */
static void test_k_work_user_submit_to_queue_fail(void)
{
	int ret = 0;

	k_sem_reset(&sync_sema);
	k_work_user_init(&work[0], common_work_handler);
	k_work_user_init(&work[1], common_work_handler);

	/* TESTPOINT: When a work item be added to a workqueue, its flag will
	 * be in pending state, before the work item be processed, it cannot
	 * be append to a workqueue another time.
	 */
	k_work_user_submit_to_queue(&user_workq, &work[0]);
	zassert_true(k_work_user_is_pending(&work[0]));
	k_work_user_submit_to_queue(&user_workq, &work[0]);

	/* Test the work item's callback function can only be invoked once */
	k_sem_take(&sync_sema, K_FOREVER);
	zassert_true(k_queue_is_empty(&user_workq.queue));
	zassert_false(k_work_user_is_pending(&work[0]));

	/* use up the memory in resource pool */
	for (int i = 0; i < 100; i++) {
		ret = k_queue_alloc_append(&user_workq.queue, &work[1]);
		if (ret == -ENOMEM) {
			break;
		}
	}

	k_work_user_submit_to_queue(&user_workq, &work[0]);
	/* if memory is used up, the work cannot be append into the workqueue */
	zassert_false(k_work_user_is_pending(&work[0]));
}


static void work_handler(struct k_work_user *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 twork_submit_1(struct k_work_user_q *work_q, struct k_work_user *w,
			   k_work_user_handler_t handler)
{
	/**TESTPOINT: init via k_work_init*/
	k_work_user_init(w, handler);
	/**TESTPOINT: check pending after work init*/
	zassert_false(k_work_user_is_pending(w));

	/**TESTPOINT: work submit to queue*/
	zassert_false(k_work_user_submit_to_queue(work_q, w),
		      "failed to submit to queue");
}

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

	for (int i = 0; i < NUM_OF_WORK; i++) {
		twork_submit_1(work_q, &work[i], work_handler);
	}
}

/**
 * @brief Test user mode work queue start before submit
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_user_queue_start()
 */
static void test_work_user_queue_start_before_submit(void)
{
	k_work_user_queue_start(&user_workq, user_tstack, STACK_SIZE,
				CONFIG_MAIN_THREAD_PRIORITY, "user.wq");
}

/**
 * @brief Setup object permissions before test_user_workq_granted_access()
 *
 * @ingroup kernel_workqueue_tests
 */
static 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()
 */
static void test_user_workq_granted_access(void)
{
	k_object_access_grant(&dummy_sema, &user_workq.thread);
}

/**
 * @brief Test work submission to work queue (user mode)
 *
 * @ingroup kernel_workqueue_tests
 *
 * @see k_work_init(), k_work_is_pending(), k_work_submit_to_queue(),
 * k_work_submit()
 */
static 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);
	}
}

void *workq_setup(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, SYNC_SEM_INIT_VAL, NUM_OF_WORK);
	k_thread_system_pool_assign(k_current_get());

	test_user_workq_granted_access_setup();
	test_k_work_user_init();

	return NULL;
}

ZTEST_USER(workqueue_api, test_workq_user_mode)
{
	/* Do not disturb the ordering of these test cases */
	test_work_user_queue_start_before_submit();
	test_user_workq_granted_access();

	/* End order-important tests */
	test_user_work_submit_to_queue_thread();
	test_k_work_user_submit_to_queue_fail();
}

ZTEST_SUITE(workqueue_api, NULL, workq_setup, NULL, NULL, NULL);
