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

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

#define TIME_OUT_TICKS  10

K_MEM_SLAB_DEFINE(cv2_mem_slab, sizeof(struct cv2_mslab),
		  CONFIG_CMSIS_V2_MEM_SLAB_MAX_COUNT, 4);

static const osMemoryPoolAttr_t init_mslab_attrs = {
	.name = "ZephyrMemPool",
	.attr_bits = 0,
	.cb_mem = NULL,
	.cb_size = 0,
	.mp_mem = NULL,
	.mp_size = 0,
};

/**
 * @brief Create and Initialize a memory pool.
 */
osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size,
				 const osMemoryPoolAttr_t *attr)
{
	struct cv2_mslab *mslab;

	BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE >=
		     CONFIG_CMSIS_V2_MEM_SLAB_MAX_DYNAMIC_SIZE,
		     "heap must be configured to be at least the max dynamic size");

	if (k_is_in_isr()) {
		return NULL;
	}

	if ((attr != NULL) && (attr->mp_size < block_count * block_size)) {
		return NULL;
	}

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

	if (k_mem_slab_alloc(&cv2_mem_slab, (void **)&mslab, K_MSEC(100)) == 0) {
		(void)memset(mslab, 0, sizeof(struct cv2_mslab));
	} else {
		return NULL;
	}

	if (attr->mp_mem == NULL) {
		__ASSERT((block_count * block_size) <=
			 CONFIG_CMSIS_V2_MEM_SLAB_MAX_DYNAMIC_SIZE,
			 "memory slab/pool size exceeds dynamic maximum");

		mslab->pool = k_calloc(block_count, block_size);
		if (mslab->pool == NULL) {
			k_mem_slab_free(&cv2_mem_slab, (void *) &mslab);
			return NULL;
		}
		mslab->is_dynamic_allocation = TRUE;
	} else {
		mslab->pool = attr->mp_mem;
		mslab->is_dynamic_allocation = FALSE;
	}

	k_mem_slab_init(&mslab->z_mslab, mslab->pool, block_size, block_count);

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

	return (osMemoryPoolId_t)mslab;
}

/**
 * @brief Allocate a memory block from a memory pool.
 */
void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
	int retval;
	void *ptr;

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

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

	if (timeout == 0U) {
		retval = k_mem_slab_alloc(
			(struct k_mem_slab *)(&mslab->z_mslab),
			(void **)&ptr, K_NO_WAIT);
	} else if (timeout == osWaitForever) {
		retval = k_mem_slab_alloc(
			(struct k_mem_slab *)(&mslab->z_mslab),
			(void **)&ptr, K_FOREVER);
	} else {
		retval = k_mem_slab_alloc(
			(struct k_mem_slab *)(&mslab->z_mslab),
			(void **)&ptr, K_TICKS(timeout));
	}

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

/**
 * @brief Return an allocated memory block back to a specific memory pool.
 */
osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

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

	/* Note: Below error code is not supported.
	 *       osErrorResource: the memory pool specified by parameter mp_id
	 *       is in an invalid memory pool state.
	 */

	k_mem_slab_free((struct k_mem_slab *)(&mslab->z_mslab), (void *)&block);

	return osOK;
}

/**
 * @brief Get name of a Memory Pool object.
 */
const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

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

/**
 * @brief Get maximum number of memory blocks in a Memory Pool.
 */
uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

	if (mslab == NULL) {
		return 0;
	} else {
		return mslab->z_mslab.num_blocks;
	}
}

/**
 * @brief Get memory block size in a Memory Pool.
 */
uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

	if (mslab == NULL) {
		return 0;
	} else {
		return mslab->z_mslab.block_size;
	}
}

/**
 * @brief Get number of memory blocks used in a Memory Pool.
 */
uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

	if (mslab == NULL) {
		return 0;
	} else {
		return k_mem_slab_num_used_get(&mslab->z_mslab);
	}
}

/**
 * @brief Get number of memory blocks available in a Memory Pool.
 */
uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

	if (mslab == NULL) {
		return 0;
	} else {
		return k_mem_slab_num_free_get(&mslab->z_mslab);
	}
}

/**
 * @brief Delete a Memory Pool object.
 */
osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
{
	struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;

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

	if (k_is_in_isr()) {
		return osErrorISR;
	}

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

	if (mslab->is_dynamic_allocation) {
		k_free(mslab->pool);
	}
	k_mem_slab_free(&cv2_mem_slab, (void *)&mslab);

	return osOK;
}
