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

#include <zephyr/kernel.h>
#include <cmsis_os.h>
#include <string.h>

/**
 * @brief Create and Initialize mail queue.
 */
osMailQId osMailCreate(const osMailQDef_t *queue_def, osThreadId thread_id)
{
	if (queue_def == NULL) {
		return NULL;
	}

	if (k_is_in_isr()) {
		return NULL;
	}

	k_mbox_init(queue_def->mbox);
	return (osMailQId)(queue_def);
}

/**
 * @brief Allocate a memory block from a mail.
 */
void *osMailAlloc(osMailQId queue_id, uint32_t millisec)
{
	osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
	char *ptr;
	int retval;

	if (queue_def == NULL) {
		return NULL;
	}

	if (millisec == 0U) {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_NO_WAIT);
	} else if (millisec == osWaitForever) {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_FOREVER);
	} else {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_MSEC(millisec));
	}

	if (retval == 0) {
		return ptr;
	} else {
		return NULL;
	}
}

/**
 * @brief Allocate a memory block from a mail and set memory block to zero.
 */
void *osMailCAlloc(osMailQId queue_id, uint32_t millisec)
{
	osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
	char *ptr;
	int retval;

	if (queue_def == NULL) {
		return NULL;
	}

	if (millisec == 0U) {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_NO_WAIT);
	} else if (millisec == osWaitForever) {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_FOREVER);
	} else {
		retval = k_mem_slab_alloc(
				(struct k_mem_slab *)(queue_def->pool),
				(void **)&ptr, K_MSEC(millisec));
	}

	if (retval == 0) {
		(void)memset(ptr, 0, queue_def->item_sz);
		return ptr;
	} else {
		return NULL;
	}
}

/**
 * @brief Put a mail to a queue.
 */
osStatus osMailPut(osMailQId queue_id, void *mail)
{
	osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
	struct k_mbox_msg mmsg;

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

	if (mail == NULL) {
		return osErrorValue;
	}

	(void)memset(&mmsg, 0, sizeof(mmsg));
	mmsg.tx_data = mail;
	mmsg.rx_source_thread = K_ANY;
	mmsg.tx_target_thread = K_ANY;

	k_mbox_async_put(queue_def->mbox, &mmsg, NULL);
	return osOK;
}

/**
 * @brief Get a mail from a queue.
 */
osEvent osMailGet(osMailQId queue_id, uint32_t millisec)
{
	osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
	struct k_mbox_msg mmsg;
	osEvent evt = {0};
	int retval;

	if (queue_def == NULL) {
		evt.status = osErrorParameter;
		return evt;
	}

	(void)memset(&mmsg, 0, sizeof(mmsg));
	mmsg.rx_source_thread = K_ANY;
	mmsg.tx_target_thread = K_ANY;

	if (millisec == 0U) {
		retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_NO_WAIT);
	} else if (millisec == osWaitForever) {
		retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_FOREVER);
	} else {
		retval = k_mbox_get(queue_def->mbox, &mmsg, NULL,
				    K_MSEC(millisec));
	}

	if (retval == 0) {
		evt.status = osEventMail;
		evt.value.p = mmsg.tx_data;
	} else if (retval == -EAGAIN) {
		evt.status = osEventTimeout;
	} else if (retval == -ENOMSG) {
		evt.status = osOK;
	} else {
		evt.status = osErrorValue;
	}

	evt.def.mail_id = queue_id;

	return evt;
}

/**
 * @brief Free a memory block from a mail.
 */
osStatus osMailFree(osMailQId queue_id, void *mail)
{
	osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;

	k_mem_slab_free((struct k_mem_slab *)(queue_def->pool), (void *) &mail);

	return osOK;
}
