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

#include <kernel_structs.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_MSG(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, 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, __ticks_to_ms(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;
}
