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

#include <ztest.h>
#include <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);
}
