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

#include <zephyr/kernel.h>
#include <string.h>
#include "wrapper.h"

K_MEM_SLAB_DEFINE(cv2_mutex_slab, sizeof(struct cv2_mutex),
		  CONFIG_CMSIS_V2_MUTEX_MAX_COUNT, 4);

static const osMutexAttr_t init_mutex_attrs = {
	.name = "ZephyrMutex",
	.attr_bits = osMutexPrioInherit,
	.cb_mem = NULL,
	.cb_size = 0,
};

/**
 * @brief Create and Initialize a Mutex object.
 */
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
{
	struct cv2_mutex *mutex;

	if (k_is_in_isr()) {
		return NULL;
	}

	if (attr == NULL) {
		attr = &init_mutex_attrs;
	}

	__ASSERT(attr->attr_bits & osMutexPrioInherit,
		 "Zephyr supports osMutexPrioInherit by default. Do not unselect it\n");

	__ASSERT(!(attr->attr_bits & osMutexRobust),
		 "Zephyr does not support osMutexRobust.\n");

	if (k_mem_slab_alloc(&cv2_mutex_slab, (void **)&mutex, K_MSEC(100)) == 0) {
		memset(mutex, 0, sizeof(struct cv2_mutex));
	} else {
		return NULL;
	}

	k_mutex_init(&mutex->z_mutex);
	mutex->state = attr->attr_bits;

	if (attr->name == NULL) {
		strncpy(mutex->name, init_mutex_attrs.name,
			sizeof(mutex->name) - 1);
	} else {
		strncpy(mutex->name, attr->name, sizeof(mutex->name) - 1);
	}

	return (osMutexId_t)mutex;
}

/**
 * @brief Wait until a Mutex becomes available.
 */
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
{
	struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;
	int status;

	if (mutex_id == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	if (timeout == osWaitForever) {
		status = k_mutex_lock(&mutex->z_mutex, K_FOREVER);
	} else if (timeout == 0U) {
		status = k_mutex_lock(&mutex->z_mutex, K_NO_WAIT);
	} else {
		status = k_mutex_lock(&mutex->z_mutex,
				      K_TICKS(timeout));
	}

	if (timeout != 0 && (status == -EAGAIN || status == -EBUSY)) {
		return osErrorTimeout;
	} else if (status != 0) {
		return osErrorResource;
	} else {
		return osOK;
	}
}

/**
 * @brief Release a Mutex that was obtained by osMutexWait.
 */
osStatus_t osMutexRelease(osMutexId_t mutex_id)
{
	struct cv2_mutex *mutex = (struct cv2_mutex *) mutex_id;

	if (mutex_id == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	if (k_mutex_unlock(&mutex->z_mutex) != 0) {
		return osErrorResource;
	}

	return osOK;
}

/**
 * @brief Delete a Mutex that was created by osMutexCreate.
 */
osStatus_t osMutexDelete(osMutexId_t mutex_id)
{
	struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;

	if (mutex_id == NULL) {
		return osErrorParameter;
	}

	if (k_is_in_isr()) {
		return osErrorISR;
	}

	/* The status code "osErrorResource" (mutex specified by parameter
	 * mutex_id is in an invalid mutex state) is not supported in Zephyr.
	 */

	k_mem_slab_free(&cv2_mutex_slab, (void *) &mutex);

	return osOK;
}


osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
{
	struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;

	if (k_is_in_isr() || (mutex == NULL)) {
		return NULL;
	}

	/* Mutex was not obtained before */
	if (mutex->z_mutex.lock_count == 0U) {
		return NULL;
	}

	return get_cmsis_thread_id(mutex->z_mutex.owner);
}

const char *osMutexGetName(osMutexId_t mutex_id)
{
	struct cv2_mutex *mutex = (struct cv2_mutex *)mutex_id;

	if (k_is_in_isr() || (mutex == NULL)) {
		return NULL;
	}

	return mutex->name;
}
