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

#include <kernel_structs.h>
#include "wrapper.h"

K_MEM_SLAB_DEFINE(cv2_semaphore_slab, sizeof(struct cv2_sem),
		  CONFIG_CMSIS_V2_SEMAPHORE_MAX_COUNT, 4);

static const osSemaphoreAttr_t init_sema_attrs = {
	.name = "ZephyrSem",
	.attr_bits = 0,
	.cb_mem = NULL,
	.cb_size = 0,
};

/**
 * @brief Create and Initialize a semaphore object.
 */
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count,
			       const osSemaphoreAttr_t *attr)
{
	struct cv2_sem *semaphore;

	if (k_is_in_isr()) {
		return NULL;
	}

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

	if (k_mem_slab_alloc(&cv2_semaphore_slab,
			     (void **)&semaphore, 100) == 0) {
		(void)memset(semaphore, 0, sizeof(struct cv2_sem));
	} else {
		return NULL;
	}

	k_sem_init(&semaphore->z_semaphore, initial_count, max_count);

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

	return (osSemaphoreId_t)semaphore;
}

/**
 * @brief Wait until a semaphore becomes available.
 */
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
{
	struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id;
	int status;

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

	/* Can be called from ISRs only if timeout is set to 0 */
	if (timeout > 0 && k_is_in_isr()) {
		return osErrorParameter;
	}

	if (timeout == osWaitForever) {
		status = k_sem_take(&semaphore->z_semaphore, K_FOREVER);
	} else if (timeout == 0) {
		status = k_sem_take(&semaphore->z_semaphore, K_NO_WAIT);
	} else {
		status = k_sem_take(&semaphore->z_semaphore,
				    __ticks_to_ms(timeout));
	}

	if (status == -EBUSY) {
		return osErrorResource;
	} else if (status == -EAGAIN) {
		return osErrorTimeout;
	} else {
		return osOK;
	}
}

uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
{
	struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;

	if (semaphore_id == NULL) {
		return 0;
	}

	return k_sem_count_get(&semaphore->z_semaphore);
}

/**
 * @brief Release a semaphore that was obtained by osSemaphoreWait.
 */
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
{
	struct cv2_sem *semaphore = (struct cv2_sem *) semaphore_id;

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

	/* All tokens have already been released */
	if (k_sem_count_get(&semaphore->z_semaphore) ==
	    semaphore->z_semaphore.limit) {
		return osErrorResource;
	}

	k_sem_give(&semaphore->z_semaphore);

	return osOK;
}

/**
 * @brief Delete a semaphore that was created by osSemaphoreCreate.
 */
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
{
	struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;

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

	if (k_is_in_isr()) {
		return osErrorISR;
	}

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

	k_mem_slab_free(&cv2_semaphore_slab, (void *) &semaphore);

	return osOK;
}

const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
{
	struct cv2_sem *semaphore = (struct cv2_sem *)semaphore_id;

	if (!k_is_in_isr() && (semaphore_id != NULL)) {
		return semaphore->name;
	} else {
		return NULL;
	}
}
