/*
 * Copyright (c) 2021 intel, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <zephyr/kernel.h>
#include <ztest_error_hook.h>

static struct k_poll_signal signal_err;
#define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)

#ifdef CONFIG_USERSPACE
/**
 * @brief Test API k_poll with error number events in user mode
 *
 * @details Using API k_poll with error number
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_num_err(void)
{
	struct k_poll_event events;

	k_poll(&events, -1, K_NO_WAIT);
}

/**
 * @brief Test API k_poll with error member of events in user mode
 *
 * @details Using API k_poll with error member
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_mem_err(void)
{
	ztest_set_fault_valid(true);
	k_poll(NULL, 3, K_NO_WAIT);
}

/**
 * @brief Test API k_poll with NULL sem event in user mode
 *
 * @details Define a poll event, and using API k_poll with NULL sem
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_type_sem_err(void)
{
	struct k_poll_event event[] = {
		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
					 K_POLL_MODE_NOTIFY_ONLY,
					 NULL),
	};

	ztest_set_fault_valid(true);
	k_poll(event, 1, K_NO_WAIT);
}

/**
 * @brief Test API k_poll with NULL signal event in user mode
 *
 * @details Define a poll, and using API k_poll with NULL signal
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_type_signal_err(void)
{
	struct k_poll_event event[] = {
		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
					 K_POLL_MODE_NOTIFY_ONLY,
					 NULL),
	};

	ztest_set_fault_valid(true);
	k_poll(event, 1, K_NO_WAIT);
}

/**
 * @brief Test API k_poll with NULL fifo event in user mode
 *
 * @details Define a poll, and using API k_poll with NULL fifo
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_type_fifo_err(void)
{
	struct k_poll_event event[] = {
		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
					 K_POLL_MODE_NOTIFY_ONLY,
					 NULL),
	};

	ztest_set_fault_valid(true);
	k_poll(event, 1, K_NO_WAIT);
}

/**
 * @brief Test API k_poll with NULL message queue event in user mode
 *
 * @details Define a poll, and using API k_poll with NULL message queue
 * as parameter to check if a error will be met.
 *
 * @see k_poll()
 *
 * @ingroup kernel_poll_tests
 */
void test_k_poll_user_type_msgq_err(void)
{
	struct k_poll_event event[] = {
		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
					 K_POLL_MODE_NOTIFY_ONLY,
					 NULL),
	};

	ztest_set_fault_valid(true);
	k_poll(event, 1, K_NO_WAIT);
}


/**
 * @brief Test API k_poll_signal_init with NULL in user mode
 *
 * @details Using API k_poll_signal_init with NULL as
 * parameter to check if a error will be met.
 *
 * @see k_poll_signal_init()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_init_null(void)
{
	ztest_set_fault_valid(true);
	k_poll_signal_init(NULL);
}

/**
 * @brief Test API k_poll_signal_check with NULL object in user mode
 *
 * @details Using API k_poll with NULL object
 * as parameter to check if a error will be met.
 *
 * @see k_poll_signal_check()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_check_obj(void)
{
	unsigned int signaled;
	int result;

	ztest_set_fault_valid(true);
	k_poll_signal_check(NULL, &signaled, &result);
}

/**
 * @brief Test API k_poll_signal_check with unread address
 * in user mode
 *
 * @details Using k_poll_signal_check with
 * unread results as parameter to check if a error
 * will be met.
 *
 * @see k_poll_signal_check()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_check_signal(void)
{
	unsigned int result;

	k_poll_signal_init(&signal_err);

	ztest_set_fault_valid(true);
	k_poll_signal_check(&signal_err, NULL, &result);
}



/**
 * @brief Test API k_poll_signal_check with unread address
 * in user mode
 *
 * @details Using k_poll_signal_check with
 * unread signaled as parameter to check if a error
 * will be met.
 *
 * @see k_poll_signal_check()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_check_result(void)
{
	int signaled;

	k_poll_signal_init(&signal_err);

	ztest_set_fault_valid(true);
	k_poll_signal_check(&signal_err, &signaled, NULL);
}

/**
 * @brief Test API k_poll_signal_raise with unread address
 * in user mode
 *
 * @details Using k_poll_signal_raise with
 * NULL as parameter to check if a error
 * will be met.
 *
 * @see k_poll_signal_raise()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_raise_null(void)
{
	int result = 0;

	ztest_set_fault_valid(true);
	k_poll_signal_raise(NULL, result);
}

/**
 * @brief Test API k_poll_signal_reset with unread address
 * in user mode
 *
 * @details Using k_poll_signal_reset with
 * NULL as parameter to check if a error
 * will be met.
 *
 * @see k_poll_signal_reset()
 *
 * @ingroup kernel_poll_tests
 */
void test_poll_signal_reset_null(void)
{
	ztest_set_fault_valid(true);
	k_poll_signal_reset(NULL);
}
#endif /* CONFIG_USERSPACE */

void test_poll_fail_grant_access(void)
{
	k_thread_access_grant(k_current_get(), &signal_err);
}
