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

#include <zephyr/ztest.h>
#include <zephyr/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 atomic_t atomic_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)
{
	int count;

	(void)atomic_inc(&atomic_count);
	count = atomic_get(&atomic_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)
{
	int count;

	k_sem_take(&limit_sem, K_FOREVER);
	(void)atomic_dec(&atomic_count);
	count = atomic_get(&atomic_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);

	(void)atomic_set(&atomic_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));

	(void)atomic_set(&atomic_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);
}
