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

#ifndef CONFIG_USERSPACE

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/sys/mutex.h>

#define HIGH_T1	 0
#define HIGH_T2	 1
#define LOW_PRO	 2

#define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

static K_THREAD_STACK_DEFINE(thread_low_stack, STACKSIZE);
static struct k_thread thread_low_data;
static K_THREAD_STACK_DEFINE(thread_high_stack1, STACKSIZE);
static struct k_thread thread_high_data1;
static K_THREAD_STACK_DEFINE(thread_high_stack2, STACKSIZE);
static struct k_thread thread_high_data2;
SYS_MUTEX_DEFINE(mutex);
static uint32_t flag[3];

/* The order of threads getting mutex is judged by index
 * self addition.
 */
static uint32_t order;

static void low_prio_wait_for_mutex(void *p1, void *p2, void *p3)
{
	struct sys_mutex *pmutex = p1;

	sys_mutex_lock(pmutex, K_FOREVER);

	flag[2] = order;

	order++;
	/* Keep mutex for a while */
	k_sleep(K_MSEC(10));

	sys_mutex_unlock(pmutex);
}

static void high_prio_t1_wait_for_mutex(void *p1, void *p2, void *p3)
{
	struct sys_mutex *pmutex = p1;

	sys_mutex_lock(pmutex, K_FOREVER);

	flag[0] = order;

	order++;
	/* Keep mutex for a while */
	k_sleep(K_MSEC(10));

	sys_mutex_unlock(pmutex);
}

static void high_prio_t2_wait_for_mutex(void *p1, void *p2, void *p3)
{
	struct sys_mutex *pmutex = p1;

	sys_mutex_lock(pmutex, K_FOREVER);

	flag[1] = order;

	order++;
	/* Keep mutex for a while */
	k_sleep(K_MSEC(10));

	sys_mutex_unlock(pmutex);
}

/**
 * @brief Test multi-threads to take mutex.
 *
 * @details Define three threads, and set a higher priority for two of them,
 * and set a lower priority for the last one. Then Add a delay between
 * creating the two high priority threads.
 * Test point:
 * 1. Any number of threads may wait on a mutex locked by others
 * simultaneously.
 * 2. When the mutex is released, it is took by the highest priority
 * thread that has waited longest.
 *
 * @ingroup kernel_mutex_tests
 */
ZTEST(mutex_complex, test_mutex_multithread_competition)
{
	int old_prio = k_thread_priority_get(k_current_get());
	int prio = 10;
	flag[0] = flag[1] = flag[2] = 0;
	order = 0;

	sys_mutex_lock(&mutex, K_NO_WAIT);

	k_thread_priority_set(k_current_get(), prio);

	k_thread_create(&thread_high_data1, thread_high_stack1, STACKSIZE,
			high_prio_t1_wait_for_mutex,
			&mutex, NULL, NULL,
			prio + 2, 0, K_NO_WAIT);

	/* Thread thread_high_data1 wait more time than thread_high_data2 */
	k_sleep(K_MSEC(10));

	k_thread_create(&thread_low_data, thread_low_stack, STACKSIZE,
			low_prio_wait_for_mutex,
			&mutex, NULL, NULL,
			prio + 4, 0, K_NO_WAIT);

	k_thread_create(&thread_high_data2, thread_high_stack2, STACKSIZE,
			high_prio_t2_wait_for_mutex,
			&mutex, NULL, NULL,
			prio + 2, 0, K_NO_WAIT);

	/* Release mutex by current thread */
	sys_mutex_unlock(&mutex);

	/* Wait for thread exiting */
	k_thread_join(&thread_low_data, K_FOREVER);
	k_thread_join(&thread_high_data1, K_FOREVER);
	k_thread_join(&thread_high_data2, K_FOREVER);

	/* The mutex should be keep by high prio t1 thread */
	zassert_true(flag[0] == HIGH_T1,
	"The highest priority thread failed to take the mutex.");

	/* The mutex should be keep by high prio t2 thread */
	zassert_true(flag[1] == HIGH_T2,
	"The higher priority thread failed to take the mutex.");

	/* The mutex should be keep by low prio thread */
	zassert_true(flag[2] == LOW_PRO,
	"The low priority thread failed to take the mutex.");

	/* Revert priority of the main thread */
	k_thread_priority_set(k_current_get(), old_prio);
}

#endif /** not CONFIG_USERSPACE */
