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

#include <ztest.h>
#include <zephyr/kernel.h>
#include <cmsis_os2.h>

#define MAX_BLOCKS      10
#define TIMEOUT_TICKS   10

struct mem_block {
	int member1;
	int member2;
};

static char __aligned(4) sample_mem[sizeof(struct mem_block) * MAX_BLOCKS];
static const osMemoryPoolAttr_t mp_attrs = {
	.name = "TestMempool",
	.attr_bits = 0,
	.cb_mem = NULL,
	.cb_size = 0,
	.mp_mem = sample_mem,
	.mp_size = sizeof(struct mem_block) * MAX_BLOCKS,
};

static void mempool_common_tests(osMemoryPoolId_t mp_id,
				 const char *expected_name)
{
	int i;
	osMemoryPoolId_t dummy_id = NULL;
	const char *name;
	struct mem_block *addr_list[MAX_BLOCKS + 1];
	osStatus_t status;

	zassert_true(osMemoryPoolGetName(dummy_id) == NULL,
		     "Something's wrong with osMemoryPoolGetName!");

	name = osMemoryPoolGetName(mp_id);
	zassert_true(strcmp(expected_name, name) == 0,
		     "Error getting mempool name");

	zassert_equal(osMemoryPoolGetCapacity(dummy_id), 0,
		      "Something's wrong with osMemoryPoolGetCapacity!");

	zassert_equal(osMemoryPoolGetCapacity(mp_id), MAX_BLOCKS,
		      "Something's wrong with osMemoryPoolGetCapacity!");

	zassert_equal(osMemoryPoolGetBlockSize(dummy_id), 0,
		      "Something's wrong with osMemoryPoolGetBlockSize!");

	zassert_equal(osMemoryPoolGetBlockSize(mp_id),
		      sizeof(struct mem_block),
		      "Something's wrong with osMemoryPoolGetBlockSize!");

	/* The memory pool should be completely available at this point */
	zassert_equal(osMemoryPoolGetCount(mp_id), 0,
		      "Something's wrong with osMemoryPoolGetCount!");
	zassert_equal(osMemoryPoolGetSpace(mp_id), MAX_BLOCKS,
		      "Something's wrong with osMemoryPoolGetSpace!");

	for (i = 0; i < MAX_BLOCKS; i++) {
		addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id,
								     osWaitForever);
		zassert_true(addr_list[i] != NULL, "mempool allocation failed");
	}

	/* The memory pool should be completely in use at this point */
	zassert_equal(osMemoryPoolGetCount(mp_id), MAX_BLOCKS,
		      "Something's wrong with osMemoryPoolGetCount!");
	zassert_equal(osMemoryPoolGetSpace(mp_id), 0,
		      "Something's wrong with osMemoryPoolGetSpace!");

	/* All blocks in mempool are allocated, any more allocation
	 * without free should fail
	 */
	addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id,
							     TIMEOUT_TICKS);
	zassert_true(addr_list[i] == NULL, "allocation happened."
		     " Something's wrong!");

	zassert_equal(osMemoryPoolFree(dummy_id, addr_list[0]),
		      osErrorParameter, "mempool free worked unexpectedly!");

	for (i = 0; i < MAX_BLOCKS; i++) {
		status = osMemoryPoolFree(mp_id, addr_list[i]);
		zassert_true(status == osOK, "mempool free failed");
	}

	zassert_equal(osMemoryPoolDelete(dummy_id), osErrorParameter,
		      "mempool delete worked unexpectedly!");

	status = osMemoryPoolDelete(mp_id);
	zassert_true(status == osOK, "mempool delete failure");
}

/**
 * @brief Test dynamic memory pool allocation and free
 *
 * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
 */
void test_mempool_dynamic(void)
{
	osMemoryPoolId_t mp_id;

	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block),
				NULL);
	zassert_true(mp_id != NULL, "mempool creation failed");

	mempool_common_tests(mp_id, "ZephyrMemPool");
}

/**
 * @brief Test memory pool allocation and free
 *
 * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
 */
void test_mempool(void)
{
	osMemoryPoolId_t mp_id;

	/* Create memory pool with invalid block size */
	mp_id = osMemoryPoolNew(MAX_BLOCKS + 1, sizeof(struct mem_block),
				&mp_attrs);
	zassert_true(mp_id == NULL, "osMemoryPoolNew worked unexpectedly!");

	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block),
				&mp_attrs);
	zassert_true(mp_id != NULL, "mempool creation failed");

	mempool_common_tests(mp_id, mp_attrs.name);
}
