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

#include <ztest.h>
#include <ztest_error_hook.h>

/* Macro declarations */
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define SEM_INIT_VAL (0U)
#define SEM_MAX_VAL  (3U)
#define TOTAL_MAX (4U)
#define STACK_NUMS 5
#define PRIO 5
#define LOW_PRIO 8
#define HIGH_PRIO 2

static K_THREAD_STACK_ARRAY_DEFINE(multi_stack_give, STACK_NUMS, STACK_SIZE);
static K_THREAD_STACK_ARRAY_DEFINE(multi_stack_take, STACK_NUMS, STACK_SIZE);

static struct k_thread multi_tid_give[STACK_NUMS];
static struct k_thread multi_tid_take[STACK_NUMS];
static struct k_sem usage_sem, sync_sem, limit_sem, uninit_sem;
static ZTEST_DMEM int flag;
static ZTEST_DMEM int count;

/**
 * @defgroup kernel_sys_sem_tests Semaphore
 * @ingroup all_tests
 * @{
 * @}
 */

static void sem_thread_give_uninit(void *p1, void *p2, void *p3)
{
	ztest_set_fault_valid(true);

	/* use sem without initialise */
	k_sem_give(&uninit_sem);

	ztest_test_fail();
}

static void sem_thread_give(void *p1, void *p2, void *p3)
{
	flag = 1;
	k_sem_give(&usage_sem);
}

static void thread_low_prio_sem_take(void *p1, void *p2, void *p3)
{
	k_sem_take(&usage_sem, K_FOREVER);

	flag = LOW_PRIO;
	k_sem_give(&sync_sem);
}

static void thread_high_prio_sem_take(void *p1, void *p2, void *p3)
{
	k_sem_take(&usage_sem, K_FOREVER);

	flag = HIGH_PRIO;
	k_sem_give(&sync_sem);
}

/**
 * @brief Test semaphore usage with multiple thread
 *
 * @details Using semaphore with some situations
 * - Use a uninitialized semaphore
 * - Use semaphore normally
 * - Use semaphore with different priority threads
 *
 * @ingroup kernel_sys_sem_tests
 */
void test_multiple_thread_sem_usage(void)
{
	k_sem_init(&usage_sem, SEM_INIT_VAL, SEM_MAX_VAL);
	k_sem_init(&sync_sem, SEM_INIT_VAL, SEM_MAX_VAL);
	/* Use a semaphore to synchronize processing between threads */
	k_sem_reset(&usage_sem);
	k_thread_create(&multi_tid_give[0], multi_stack_give[0], STACK_SIZE,
			sem_thread_give, NULL, NULL,
			NULL, PRIO, K_USER | K_INHERIT_PERMS,
			K_NO_WAIT);

	k_sem_take(&usage_sem, K_FOREVER);
	zassert_equal(flag, 1, "value != 1");
	zassert_equal(k_sem_count_get(&usage_sem), 0, "sem not be took");

	k_sem_reset(&usage_sem);
	/* Use sem with different priority thread */
	k_thread_create(&multi_tid_take[0], multi_stack_take[0], STACK_SIZE,
			thread_low_prio_sem_take, NULL, NULL,
			NULL, LOW_PRIO, K_USER | K_INHERIT_PERMS,
			K_NO_WAIT);

	k_thread_create(&multi_tid_take[1], multi_stack_take[1], STACK_SIZE,
			thread_high_prio_sem_take, NULL, NULL,
			NULL, HIGH_PRIO, K_USER | K_INHERIT_PERMS,
			K_NO_WAIT);

	k_sleep(K_MSEC(50));

	/* Verify if the high prio thread take sem first */
	k_sem_give(&usage_sem);
	k_sem_take(&sync_sem, K_FOREVER);
	zassert_equal(flag, HIGH_PRIO, "high prio value error");

	k_sem_give(&usage_sem);
	k_sem_take(&sync_sem, K_FOREVER);
	zassert_equal(flag, LOW_PRIO, "low prio value error");

	k_thread_join(&multi_tid_give[0], K_FOREVER);
	k_thread_join(&multi_tid_take[0], K_FOREVER);
	k_thread_join(&multi_tid_take[1], K_FOREVER);

	k_thread_create(&multi_tid_give[1], multi_stack_give[1], STACK_SIZE,
			sem_thread_give_uninit, NULL, NULL,
			NULL, PRIO, K_USER | K_INHERIT_PERMS,
			K_NO_WAIT);
	k_sleep(K_MSEC(20));
	k_thread_join(&multi_tid_give[1], K_FOREVER);
}

static void multi_thread_sem_give(void *p1, void *p2, void *p3)
{
	count++;
	k_sem_give(&limit_sem);

	if (count < TOTAL_MAX)
		zassert_equal(k_sem_count_get(&limit_sem), count, "multi get sem error");
	else
		zassert_equal(k_sem_count_get(&limit_sem), SEM_MAX_VAL, "count > SEM_MAX_VAL");

	k_sem_take(&sync_sem, K_FOREVER);
}

static void multi_thread_sem_take(void *p1, void *p2, void *p3)
{
	k_sem_take(&limit_sem, K_FOREVER);
	count--;

	if (count >= 0)
		zassert_equal(k_sem_count_get(&limit_sem), count, "multi take sem error");
	else
		zassert_equal(k_sem_count_get(&limit_sem), 0, "count < SEM_INIT_VAL");

	k_sem_give(&sync_sem);
}

/**
 * @brief Test max semaphore can be give and take with multiple thread
 *
 * @details
 * - Define and initialize semaphore and thread.
 * - Give sem by multiple threads.
 * - Verify more than max count about semaphore can reach.
 * - Take sem by multiple threads and verify if sem count is correct.
 *
 * @ingroup kernel_sys_sem_tests
 */
void test_multi_thread_sem_limit(void)
{
	k_sem_init(&limit_sem, SEM_INIT_VAL, SEM_MAX_VAL);
	k_sem_init(&sync_sem, SEM_INIT_VAL, SEM_MAX_VAL);

	count = 0;
	for (int i = 1; i <= TOTAL_MAX; i++) {
		k_thread_create(&multi_tid_give[i], multi_stack_give[i], STACK_SIZE,
				multi_thread_sem_give, NULL, NULL, NULL,
				i, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
	}

	k_sleep(K_MSEC(50));

	count = SEM_MAX_VAL;
	for (int i = 1; i <= TOTAL_MAX; i++) {
		k_thread_create(&multi_tid_take[i], multi_stack_take[i], STACK_SIZE,
				multi_thread_sem_take, NULL, NULL, NULL,
				PRIO, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
	}
}

void test_main(void)
{
	k_thread_access_grant(k_current_get(), &usage_sem, &sync_sem, &limit_sem,
			      &multi_tid_give[0], &multi_tid_give[1],
			      &multi_tid_give[2], &multi_tid_give[3],
			      &multi_tid_give[4], &multi_tid_take[4],
			      &multi_tid_take[2], &multi_tid_take[3],
			      &multi_tid_take[0], &multi_tid_take[1],
			      &multi_tid_give[5], &multi_tid_take[5],
			      &multi_stack_take[0], &multi_stack_take[1],
			      &multi_stack_take[3], &multi_stack_take[4],
			      &multi_stack_take[2], &multi_stack_give[0],
			      &multi_stack_give[1], &multi_stack_give[2],
			      &multi_stack_give[3], &multi_stack_give[4]);

	ztest_test_suite(test_kernel_sys_sem,
			 ztest_1cpu_user_unit_test(test_multiple_thread_sem_usage),
			 ztest_1cpu_user_unit_test(test_multi_thread_sem_limit));
	ztest_run_test_suite(test_kernel_sys_sem);
}
