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

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

#define WAIT_TICKS      5
#define TIMEOUT_TICKS   (10 + WAIT_TICKS)
#define STACKSZ         CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE

int max_mtx_cnt = CONFIG_CMSIS_V2_MUTEX_MAX_COUNT;
const osMutexAttr_t mutex_attr = {
	"myMutex",
	osMutexRecursive | osMutexPrioInherit,
	NULL,
	0U
};

void cleanup_max_mutex(osMutexId_t *mutex_ids)
{
	int mutex_count = 0;
	osStatus_t status;

	for (mutex_count = 0; mutex_count < max_mtx_cnt; mutex_count++) {
		status = osMutexDelete(mutex_ids[mutex_count]);
		zassert_true(status == osOK, "Mutex delete fail");
	}
}

void test_max_mutex(void)
{
	osMutexId_t mutex_ids[CONFIG_CMSIS_V2_MUTEX_MAX_COUNT + 1];
	int mtx_cnt = 0;

	/* Try mutex creation for more than maximum count */
	for (mtx_cnt = 0; mtx_cnt < max_mtx_cnt + 1; mtx_cnt++) {
		mutex_ids[mtx_cnt] = osMutexNew(&mutex_attr);
		if (mtx_cnt == max_mtx_cnt) {
			zassert_true(mutex_ids[mtx_cnt] == NULL,
				     "Mutex creation pass unexpectedly after max count");
			cleanup_max_mutex(mutex_ids);
		} else {
			zassert_true(mutex_ids[mtx_cnt] != NULL,
				     "Multiple mutex creation failed before max count");
		}
	}
}

ZTEST(cmsis_mutex, test_mutex)
{
	osMutexId_t mutex_id = 0;
	osThreadId_t id;
	osStatus_t status;
	const char *name;

	/* Try deleting invalid mutex object */
	status = osMutexDelete(mutex_id);
	zassert_true(status == osErrorParameter,
		     "Invalid Mutex deleted unexpectedly!");

	mutex_id = osMutexNew(&mutex_attr);
	zassert_true(mutex_id != NULL, "Mutex1 creation failed");

	name = osMutexGetName(mutex_id);
	zassert_true(strcmp(mutex_attr.name, name) == 0,
		     "Error getting Mutex name");

	/* Try to release mutex without obtaining it */
	status = osMutexRelease(mutex_id);
	zassert_true(status == osErrorResource, "Mutex released unexpectedly!");

	/* Try figuring out the owner for a Mutex which has not been
	 * acquired by any thread yet.
	 */
	id = osMutexGetOwner(mutex_id);
	zassert_true(id == NULL, "Something wrong with MutexGetOwner!");

	status = osMutexAcquire(mutex_id, 0);
	zassert_true(status == osOK, "Mutex wait failure");

	id = osMutexGetOwner(mutex_id);
	zassert_equal(id, osThreadGetId(), "Current thread is not the owner!");

	/* Try to acquire an already acquired mutex */
	status = osMutexAcquire(mutex_id, 0);
	zassert_true(status == osOK, "Mutex wait failure");

	status = osMutexRelease(mutex_id);
	zassert_true(status == osOK, "Mutex release failure");

	/* Release mutex again as it was acquired twice */
	status = osMutexRelease(mutex_id);
	zassert_true(status == osOK, "Mutex release failure");

	/* Try to release mutex that was already released */
	status = osMutexRelease(mutex_id);
	zassert_true(status == osErrorResource, "Mutex released unexpectedly!");

	status = osMutexDelete(mutex_id);
	zassert_true(status == osOK, "Mutex delete failure");

	/* Try mutex creation for more than maximum allowed count */
	test_max_mutex();
}

void tThread_entry_lock_timeout(void *arg)
{
	osStatus_t status;
	osThreadId_t id;

	/* Mutex cannot be acquired/released here as it is still held
	 * by the other thread. Try with and without timeout.
	 */
	status = osMutexAcquire((osMutexId_t)arg, 0);
	zassert_true(status == osErrorResource);

	status = osMutexAcquire((osMutexId_t)arg, WAIT_TICKS);
	zassert_true(status == osErrorTimeout);

	status = osMutexRelease((osMutexId_t)arg);
	zassert_true(status == osErrorResource, "Mutex unexpectedly released");

	id = osMutexGetOwner((osMutexId_t)arg);
	zassert_not_equal(id, osThreadGetId(),
			  "Unexpectedly, current thread is the mutex owner!");

	/* This delay ensures that the mutex gets released by the other
	 * thread in the meantime
	 */
	osDelay(TIMEOUT_TICKS);

	/* Now that the mutex is free, it should be possible to acquire
	 * and release it.
	 */
	status = osMutexAcquire((osMutexId_t)arg, TIMEOUT_TICKS);
	zassert_true(status == osOK);
	osMutexRelease((osMutexId_t)arg);
}

static K_THREAD_STACK_DEFINE(test_stack, STACKSZ);
static osThreadAttr_t thread_attr = {
	.name = "Mutex_check",
	.attr_bits = osThreadDetached,
	.cb_mem = NULL,
	.cb_size = 0,
	.stack_mem = &test_stack,
	.stack_size = STACKSZ,
	.priority = osPriorityNormal,
	.tz_module = 0,
	.reserved = 0
};

ZTEST(cmsis_mutex, test_mutex_lock_timeout)
{
	osThreadId_t id;
	osMutexId_t mutex_id;
	osStatus_t status;

	mutex_id = osMutexNew(&mutex_attr);
	zassert_true(mutex_id != NULL, "Mutex2 creation failed");

	id = osThreadNew(tThread_entry_lock_timeout, mutex_id, &thread_attr);
	zassert_true(id != NULL, "Thread creation failed");

	status = osMutexAcquire(mutex_id, osWaitForever);
	zassert_true(status == osOK, "Mutex wait failure");

	/* wait for spawn thread to take action */
	osDelay(TIMEOUT_TICKS);

	/* Release the mutex to be used by the other thread */
	osMutexRelease(mutex_id);
	osDelay(TIMEOUT_TICKS);

	osMutexDelete(mutex_id);
}
ZTEST_SUITE(cmsis_mutex, NULL, NULL, NULL, NULL, NULL);
