/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/ztest.h>

#define TIMEOUT 500
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define THREAD_HIGH_PRIORITY 1
#define THREAD_MID_PRIORITY 3
#define THREAD_LOW_PRIORITY 5

/* use to pass case type to threads */
static ZTEST_DMEM int case_type;
static ZTEST_DMEM int thread_ret = TC_FAIL;

/**TESTPOINT: init via K_MUTEX_DEFINE*/
K_MUTEX_DEFINE(kmutex);
static struct k_mutex mutex;

static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
static K_THREAD_STACK_DEFINE(tstack2, STACK_SIZE);
static K_THREAD_STACK_DEFINE(tstack3, STACK_SIZE);
static struct k_thread tdata;
static struct k_thread tdata2;
static struct k_thread tdata3;

static void tThread_entry_lock_forever(void *p1, void *p2, void *p3)
{
	zassert_false(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0,
		      "access locked resource from spawn thread");
	/* should not hit here */
}

static void tThread_entry_lock_no_wait(void *p1, void *p2, void *p3)
{
	zassert_true(k_mutex_lock((struct k_mutex *)p1, K_NO_WAIT) != 0);
	TC_PRINT("bypass locked resource from spawn thread\n");
}

static void tThread_entry_lock_timeout_fail(void *p1, void *p2, void *p3)
{
	zassert_true(k_mutex_lock((struct k_mutex *)p1,
				  K_MSEC(TIMEOUT - 100)) != 0, NULL);
	TC_PRINT("bypass locked resource from spawn thread\n");
}

static void tThread_entry_lock_timeout_pass(void *p1, void *p2, void *p3)
{
	zassert_true(k_mutex_lock((struct k_mutex *)p1,
				  K_MSEC(TIMEOUT + 100)) == 0, NULL);
	TC_PRINT("access resource from spawn thread\n");
	k_mutex_unlock((struct k_mutex *)p1);
}

static void tmutex_test_lock(struct k_mutex *pmutex,
			     void (*entry_fn)(void *, void *, void *))
{
	k_mutex_init(pmutex);
	k_thread_create(&tdata, tstack, STACK_SIZE,
			entry_fn, pmutex, NULL, NULL,
			K_PRIO_PREEMPT(0),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);
	zassert_true(k_mutex_lock(pmutex, K_FOREVER) == 0);
	TC_PRINT("access resource from main thread\n");

	/* wait for spawn thread to take action */
	k_msleep(TIMEOUT);
}

static void tmutex_test_lock_timeout(struct k_mutex *pmutex,
				     void (*entry_fn)(void *, void *, void *))
{
	/**TESTPOINT: test k_mutex_init mutex*/
	k_mutex_init(pmutex);
	k_thread_create(&tdata, tstack, STACK_SIZE,
			entry_fn, pmutex, NULL, NULL,
			K_PRIO_PREEMPT(0),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);
	zassert_true(k_mutex_lock(pmutex, K_FOREVER) == 0);
	TC_PRINT("access resource from main thread\n");

	/* wait for spawn thread to take action */
	k_msleep(TIMEOUT);
	k_mutex_unlock(pmutex);
	k_msleep(TIMEOUT);

}

static void tmutex_test_lock_unlock(struct k_mutex *pmutex)
{
	k_mutex_init(pmutex);
	zassert_true(k_mutex_lock(pmutex, K_FOREVER) == 0,
		     "fail to lock K_FOREVER");
	k_mutex_unlock(pmutex);
	zassert_true(k_mutex_lock(pmutex, K_NO_WAIT) == 0,
		     "fail to lock K_NO_WAIT");
	k_mutex_unlock(pmutex);
	zassert_true(k_mutex_lock(pmutex, K_MSEC(TIMEOUT)) == 0,
		     "fail to lock TIMEOUT");
	k_mutex_unlock(pmutex);
}

static void tThread_T1_priority_inheritance(void *p1, void *p2, void *p3)
{
	/* t1 will get mutex first */
	zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0,
		      "access locked resource from spawn thread T1");

	/* record its original priority */
	int priority_origin = k_thread_priority_get((k_tid_t)p2);

	/* wait for a time period to see if priority inheritance happened */
	k_sleep(K_MSEC(500));

	int priority = k_thread_priority_get((k_tid_t)p2);

	if (case_type == 1) {
		zassert_equal(priority, THREAD_HIGH_PRIORITY,
			"priority inheritance not happened!");

		k_mutex_unlock((struct k_mutex *)p1);

		/* check if priority set back to original one */
		priority = k_thread_priority_get((k_tid_t)p2);

		zassert_equal(priority, priority_origin,
			"priority inheritance adjust back not happened!");
	} else if (case_type == 2) {
		zassert_equal(priority, priority_origin,
			"priority inheritance should not be happened!");

		/* wait for t2 timeout to get mutex*/
		k_sleep(K_MSEC(TIMEOUT));

		k_mutex_unlock((struct k_mutex *)p1);
	} else if (case_type == 3) {
		zassert_equal(priority, THREAD_HIGH_PRIORITY,
			"priority inheritance not happened!");

		/* wait for t2 timeout to get mutex*/
		k_sleep(K_MSEC(TIMEOUT));

		k_mutex_unlock((struct k_mutex *)p1);
	} else {
		zassert_true(0, "should not be here!");
	}
}

static void tThread_T2_priority_inheritance(void *p1, void *p2, void *p3)
{
	if (case_type == 1) {
		zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0,
		      "access locked resource from spawn thread T2");

		k_mutex_unlock((struct k_mutex *)p1);
	} else if (case_type == 2 || case_type == 3) {
		zassert_false(k_mutex_lock((struct k_mutex *)p1,
				K_MSEC(100)) == 0,
				"T2 should not get the resource");
	} else {
		zassert_true(0, "should not be here!");
	}
}

static void tThread_lock_with_time_period(void *p1, void *p2, void *p3)
{
	zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0,
		      "access locked resource from spawn thread");

	/* This thread will hold mutex for 600 ms, then release it */
	k_sleep(K_MSEC(TIMEOUT + 100));

	k_mutex_unlock((struct k_mutex *)p1);
}

static void tThread_waiter(void *p1, void *p2, void *p3)
{
	/* This thread participates in recursive locking tests */
	/* Wait for mutex to be released */
	zassert_true(k_mutex_lock((struct k_mutex *)p1, K_FOREVER) == 0,
			"Failed to get the test_mutex");

	/* keep the next waiter waiting for a while */
	thread_ret = TC_PASS;
	k_mutex_unlock((struct k_mutex *)p1);
}

/*test cases*/
ZTEST_USER(mutex_api_1cpu, test_mutex_reent_lock_forever)
{
	/**TESTPOINT: test k_mutex_init mutex*/
	k_mutex_init(&mutex);
	tmutex_test_lock(&mutex, tThread_entry_lock_forever);
	k_thread_abort(&tdata);

	/**TESTPOINT: test K_MUTEX_DEFINE mutex*/
	tmutex_test_lock(&kmutex, tThread_entry_lock_forever);
	k_thread_abort(&tdata);
}

ZTEST_USER(mutex_api, test_mutex_reent_lock_no_wait)
{
	/**TESTPOINT: test k_mutex_init mutex*/
	tmutex_test_lock(&mutex, tThread_entry_lock_no_wait);

	/**TESTPOINT: test K_MUTEX_DEFINE mutex*/
	tmutex_test_lock(&kmutex, tThread_entry_lock_no_wait);
}

ZTEST_USER(mutex_api, test_mutex_reent_lock_timeout_fail)
{
	/**TESTPOINT: test k_mutex_init mutex*/
	tmutex_test_lock_timeout(&mutex, tThread_entry_lock_timeout_fail);

	/**TESTPOINT: test K_MUTEX_DEFINE mutex*/
	tmutex_test_lock_timeout(&kmutex, tThread_entry_lock_no_wait);
}

ZTEST_USER(mutex_api_1cpu, test_mutex_reent_lock_timeout_pass)
{
	/**TESTPOINT: test k_mutex_init mutex*/
	tmutex_test_lock_timeout(&mutex, tThread_entry_lock_timeout_pass);

	/**TESTPOINT: test K_MUTEX_DEFINE mutex*/
	tmutex_test_lock_timeout(&kmutex, tThread_entry_lock_no_wait);
}

ZTEST_USER(mutex_api_1cpu, test_mutex_lock_unlock)
{
	/**TESTPOINT: test k_mutex_init mutex*/
	tmutex_test_lock_unlock(&mutex);

	/**TESTPOINT: test K_MUTEX_DEFINE mutex*/
	tmutex_test_lock_unlock(&kmutex);
}

/**
 * @brief Test recursive mutex
 * @details To verify that getting a lock of a mutex already locked will
 * succeed and waiters will be unblocked only when the number of locks
 * reaches zero.
 * @ingroup kernel_mutex_tests
 */
ZTEST_USER(mutex_api, test_mutex_recursive)
{
	k_mutex_init(&mutex);

	/**TESTPOINT: when mutex has no owner, we cannot unlock it */
	zassert_true(k_mutex_unlock(&mutex) == -EINVAL,
			"fail: mutex has no owner");

	zassert_true(k_mutex_lock(&mutex, K_NO_WAIT) == 0,
			"Failed to lock mutex");

	/**TESTPOINT: lock the mutex recursively */
	zassert_true(k_mutex_lock(&mutex, K_NO_WAIT) == 0,
		"Failed to recursively lock mutex");

	thread_ret = TC_FAIL;
	/* Spawn a waiter thread */
	k_thread_create(&tdata3, tstack3, STACK_SIZE,
			(k_thread_entry_t)tThread_waiter, &mutex, NULL, NULL,
			K_PRIO_PREEMPT(12),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	zassert_true(thread_ret == TC_FAIL,
		"waiter thread should block on the recursively locked mutex");

	zassert_true(k_mutex_unlock(&mutex) == 0, "fail to unlock");

	/**TESTPOINT: unlock the mutex recursively */
	zassert_true(thread_ret == TC_FAIL,
		"waiter thread should still block on the locked mutex");

	zassert_true(k_mutex_unlock(&mutex) == 0, "fail to unlock");

	/* Give thread_waiter a chance to get the mutex */
	k_sleep(K_MSEC(1));

	/**TESTPOINT: waiter thread got the mutex */
	zassert_true(thread_ret == TC_PASS,
			"waiter thread can't take the mutex");
}

/**
 * @brief Test mutex's priority inheritance mechanism
 * @details To verify mutex provide priority inheritance to prevent priority
 * inversion, and there are 3 cases need to run.
 * The thread T1 hold the mutex first and cases list as below:
 * - case 1. When priority T2 > T1, priority inheritance happened.
 * - case 2. When priority T1 > T2, priority inheritance won't happened.
 * - case 3. When priority T2 > T3 > T1, priority inheritance happened but T2
 *   wait for timeout and T3 got the mutex.
 * @ingroup kernel_mutex_tests
 */
ZTEST_USER(mutex_api_1cpu, test_mutex_priority_inheritance)
{
	/**TESTPOINT: run test case 1, given priority T1 < T2 */
	k_mutex_init(&mutex);

	/* we told thread which case runs now */
	case_type = 1;

	/* spawn a lower priority thread t1 for holding the mutex */
	k_thread_create(&tdata, tstack, STACK_SIZE,
		(k_thread_entry_t)tThread_T1_priority_inheritance,
			&mutex, &tdata, NULL,
			K_PRIO_PREEMPT(THREAD_LOW_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t1 to take action */
	k_msleep(TIMEOUT);

	/**TESTPOINT: The current thread does not own the mutex.*/
	zassert_true(k_mutex_unlock(&mutex) == -EPERM,
			"fail: current thread does not own the mutex");

	/* spawn a higher priority thread t2 for holding the mutex */
	k_thread_create(&tdata2, tstack2, STACK_SIZE,
		(k_thread_entry_t)tThread_T2_priority_inheritance,
			&mutex, &tdata2, NULL,
			K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t2 to take action */
	k_msleep(TIMEOUT+1000);

	/**TESTPOINT: run test case 2, given priority T1 > T2, this means
	 * priority inheritance won't happen.
	 */
	k_mutex_init(&mutex);
	case_type = 2;

	/* spawn a lower priority thread t1 for holding the mutex */
	k_thread_create(&tdata, tstack, STACK_SIZE,
		(k_thread_entry_t)tThread_T1_priority_inheritance,
			&mutex, &tdata, NULL,
			K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t1 to take action */
	k_msleep(TIMEOUT);

	/* spawn a higher priority thread t2 for holding the mutex */
	k_thread_create(&tdata2, tstack2, STACK_SIZE,
		(k_thread_entry_t)tThread_T2_priority_inheritance,
			&mutex, &tdata2, NULL,
			K_PRIO_PREEMPT(THREAD_LOW_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t2 to take action */
	k_msleep(TIMEOUT+1000);

	/**TESTPOINT: run test case 3, given priority T1 < T3 < T2, but t2 do
	 * not get mutex due to timeout.
	 */
	k_mutex_init(&mutex);
	case_type = 3;

	/* spawn a lower priority thread t1 for holding the mutex */
	k_thread_create(&tdata, tstack, STACK_SIZE,
		(k_thread_entry_t)tThread_T1_priority_inheritance,
			&mutex, &tdata, NULL,
			K_PRIO_PREEMPT(THREAD_LOW_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t1 to take action */
	k_msleep(TIMEOUT);

	/* spawn a higher priority thread t2 for holding the mutex */
	k_thread_create(&tdata2, tstack2, STACK_SIZE,
		(k_thread_entry_t)tThread_T2_priority_inheritance,
			&mutex, &tdata2, NULL,
			K_PRIO_PREEMPT(THREAD_HIGH_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* spawn a higher priority thread t3 for holding the mutex */
	k_thread_create(&tdata3, tstack3, STACK_SIZE,
		(k_thread_entry_t)tThread_lock_with_time_period,
			&mutex, &tdata3, NULL,
			K_PRIO_PREEMPT(THREAD_MID_PRIORITY),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* wait for spawn thread t2 and t3 to take action */
	k_msleep(TIMEOUT+1000);
}

static void tThread_mutex_lock_should_fail(void *p1, void *p2, void *p3)
{
	k_timeout_t timeout;
	struct k_mutex *mutex = (struct k_mutex *)p1;

	timeout.ticks = 0;
	timeout.ticks |= (uint64_t)(uintptr_t)p2 << 32;
	timeout.ticks |= (uint64_t)(uintptr_t)p3 << 0;

	zassert_equal(-EAGAIN, k_mutex_lock(mutex, timeout), NULL);
}

/**
 * @brief Test fix for subtle race during priority inversion
 *
 * - A low priority thread (Tlow) locks mutex A.
 * - A high priority thread (Thigh) blocks on mutex A, boosting the priority
 *   of Tlow.
 * - Thigh times out waiting for mutex A.
 * - Before Thigh has a chance to execute, Tlow unlocks mutex A (which now
 *   has no owner) and drops its own priority.
 * - Thigh now gets a chance to execute and finds that it timed out, and
 *   then enters the block of code to lower the priority of the thread that
 *   owns mutex A (now nobody).
 * - Thigh tries to the dereference the owner of mutex A (which is nobody,
 *   and thus it is NULL). This leads to an exception.
 *
 * @ingroup kernel_mutex_tests
 *
 * @see k_mutex_lock()
 */
ZTEST(mutex_api_1cpu, test_mutex_timeout_race_during_priority_inversion)
{
	k_timeout_t timeout;
	uintptr_t timeout_upper;
	uintptr_t timeout_lower;
	int helper_prio = k_thread_priority_get(k_current_get()) + 1;

	k_mutex_init(&mutex);

	/* align to tick boundary */
	k_sleep(K_TICKS(1));

	/* allow non-kobject data to be shared (via registers) */
	timeout = K_TIMEOUT_ABS_TICKS(k_uptime_ticks()
		+ CONFIG_TEST_MUTEX_API_THREAD_CREATE_TICKS);
	timeout_upper = timeout.ticks >> 32;
	timeout_lower = timeout.ticks & BIT64_MASK(32);

	k_mutex_lock(&mutex, K_FOREVER);
	k_thread_create(&tdata, tstack, K_THREAD_STACK_SIZEOF(tstack),
			tThread_mutex_lock_should_fail, &mutex, (void *)timeout_upper,
			(void *)timeout_lower, helper_prio,
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	k_thread_priority_set(k_current_get(), K_HIGHEST_THREAD_PRIO);

	k_sleep(timeout);

	k_mutex_unlock(&mutex);
}

static void *mutex_api_tests_setup(void)
{
#ifdef CONFIG_USERSPACE
	k_thread_access_grant(k_current_get(), &tdata, &tstack, &tdata2,
				&tstack2, &tdata3, &tstack3, &kmutex,
				&mutex);
#endif
	return NULL;
}

ZTEST_SUITE(mutex_api, NULL, mutex_api_tests_setup, NULL, NULL, NULL);
ZTEST_SUITE(mutex_api_1cpu, NULL, mutex_api_tests_setup,
			ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
