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

#include <zephyr/ztest.h>
#include "test_mslab.h"

/* TESTPOINT: Statically define and initialize a memory slab*/
K_MEM_SLAB_DEFINE(kmslab, BLK_SIZE, BLK_NUM, BLK_ALIGN);
static char __aligned(BLK_ALIGN) tslab[BLK_SIZE * BLK_NUM];
static struct k_mem_slab mslab;
K_SEM_DEFINE(SEM_HELPERDONE, 0, 1);
K_SEM_DEFINE(SEM_REGRESSDONE, 0, 1);
static K_THREAD_STACK_DEFINE(stack, STACKSIZE);
static struct k_thread HELPER;

void *mslab_setup(void)
{
	k_mem_slab_init(&mslab, tslab, BLK_SIZE, BLK_NUM);

	return NULL;
}

void tmslab_alloc_free(void *data)
{
	struct k_mem_slab *pslab = (struct k_mem_slab *)data;
	void *block[BLK_NUM];

	(void)memset(block, 0, sizeof(block));
	/*
	 * TESTPOINT: The memory slab's buffer contains @a slab_num_blocks
	 * memory blocks that are @a slab_block_size bytes long.
	 */
	for (int i = 0; i < BLK_NUM; i++) {
		/* TESTPOINT: Allocate memory from a memory slab.*/
		/* TESTPOINT: @retval 0 Memory allocated.*/
		zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0,
			     NULL);
		/*
		 * TESTPOINT: The block address area pointed at by @a mem is set
		 * to the starting address of the memory block.
		 */
		zassert_not_null(block[i], NULL);
	}
	for (int i = 0; i < BLK_NUM; i++) {
		/* TESTPOINT: Free memory allocated from a memory slab.*/
		k_mem_slab_free(pslab, block[i]);
	}
}

static void tmslab_alloc_align(void *data)
{
	struct k_mem_slab *pslab = (struct k_mem_slab *)data;
	void *block[BLK_NUM];

	for (int i = 0; i < BLK_NUM; i++) {
		zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0,
			     NULL);
		/*
		 * TESTPOINT: To ensure that each memory block is similarly
		 * aligned to this boundary
		 */
		zassert_true((uintptr_t)block[i] % BLK_ALIGN == 0U);
	}
	for (int i = 0; i < BLK_NUM; i++) {
		k_mem_slab_free(pslab, block[i]);
	}
}

static void tmslab_alloc_timeout(void *data)
{
	struct k_mem_slab *pslab = (struct k_mem_slab *)data;
	void *block[BLK_NUM], *block_fail;
	int64_t tms;
	int err;

	for (int i = 0; i < BLK_NUM; i++) {
		zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0,
			     NULL);
	}

	/* TESTPOINT: Use K_NO_WAIT to return without waiting*/
	/* TESTPOINT: -ENOMEM Returned without waiting.*/
	zassert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM,
		      NULL);
	tms = k_uptime_get();
	err = k_mem_slab_alloc(pslab, &block_fail, K_MSEC(TIMEOUT));
	if (IS_ENABLED(CONFIG_MULTITHREADING)) {
		/* TESTPOINT: -EAGAIN Waiting period timed out*/
		zassert_equal(err, -EAGAIN);
		/*
		 * TESTPOINT: timeout Maximum time to wait for operation to
		 * complete (in milliseconds)
		 */
		zassert_true(k_uptime_delta(&tms) >= TIMEOUT);
	} else {
		/* If no multithreading any timeout is treated as K_NO_WAIT */
		zassert_equal(err, -ENOMEM);
		zassert_true(k_uptime_delta(&tms) < TIMEOUT);
	}

	for (int i = 0; i < BLK_NUM; i++) {
		k_mem_slab_free(pslab, block[i]);
	}
}

static void tmslab_used_get(void *data)
{
	struct k_mem_slab *pslab = (struct k_mem_slab *)data;
	void *block[BLK_NUM], *block_fail;

	for (int i = 0; i < BLK_NUM; i++) {
		zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0,
			     NULL);
		/* TESTPOINT: Get the number of used blocks in a memory slab.*/
		zassert_equal(k_mem_slab_num_used_get(pslab), i + 1);
		/*
		 * TESTPOINT: Get the number of unused blocks in a memory slab.
		 */
		zassert_equal(k_mem_slab_num_free_get(pslab), BLK_NUM - 1 - i);
	}

	zassert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM,
		      NULL);
	/* free get on allocation failure*/
	zassert_equal(k_mem_slab_num_free_get(pslab), 0);
	/* used get on allocation failure*/
	zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM);

	zassert_equal(k_mem_slab_alloc(pslab, &block_fail, K_MSEC(TIMEOUT)),
		      IS_ENABLED(CONFIG_MULTITHREADING) ? -EAGAIN : -ENOMEM,
		      NULL);
	zassert_equal(k_mem_slab_num_free_get(pslab), 0);
	zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM);

	for (int i = 0; i < BLK_NUM; i++) {
		k_mem_slab_free(pslab, block[i]);
		zassert_equal(k_mem_slab_num_free_get(pslab), i + 1);
		zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM - 1 - i);
	}
}

static void helper_thread(void *p0, void *p1, void *p2)
{
	void *ptr[BLK_NUM];           /* Pointer to memory block */

	ARG_UNUSED(p0);
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);

	(void)memset(ptr, 0, sizeof(ptr));

	k_sem_take(&SEM_REGRESSDONE, K_FOREVER);

	/* Get all blocks from the memory slab */
	for (int i = 0; i < BLK_NUM; i++) {
		/* Verify number of used blocks in the map */
		zassert_equal(k_mem_slab_num_used_get(&kmslab), i,
			      "Failed k_mem_slab_num_used_get");

		/* Get memory block */
		zassert_equal(k_mem_slab_alloc(&kmslab, &ptr[i], K_NO_WAIT), 0,
			      "Failed k_mem_slab_alloc");
	}

	k_sem_give(&SEM_HELPERDONE);

	k_sem_take(&SEM_REGRESSDONE, K_FOREVER);
	k_mem_slab_free(&kmslab, ptr[0]);


	k_sem_take(&SEM_REGRESSDONE, K_FOREVER);

	/* Free all the other blocks.  The first block are freed by this task */
	for (int i = 1; i < BLK_NUM; i++) {
		k_mem_slab_free(&kmslab, ptr[i]);
	}

	k_sem_give(&SEM_HELPERDONE);

}  /* helper thread */

/*test cases*/
/**
 * @brief Initialize the memory slab using k_mem_slab_init()
 * and allocates/frees blocks.
 *
 * @details Initialize 3 memory blocks of block size 8 bytes
 * using @see k_mem_slab_init() and check if number of used blocks
 * is 0 and free blocks is equal to number of blocks initialized.
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_kinit)
{
	/* if a block_size is not word aligned, slab init return error */
	zassert_equal(k_mem_slab_init(&mslab, tslab, BLK_SIZE + 1, BLK_NUM),
				-EINVAL, NULL);
	k_mem_slab_init(&mslab, tslab, BLK_SIZE, BLK_NUM);
	zassert_equal(k_mem_slab_num_used_get(&mslab), 0);
	zassert_equal(k_mem_slab_num_free_get(&mslab), BLK_NUM);
}

/**
 * @brief Verify K_MEM_SLAB_DEFINE() with allocates/frees blocks.
 *
 * @details Initialize 3 memory blocks of block size 8 bytes
 * using @see K_MEM_SLAB_DEFINE() and check if number of used blocks
 * is 0 and free blocks is equal to number of blocks initialized.
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_kdefine)
{
	zassert_equal(k_mem_slab_num_used_get(&kmslab), 0);
	zassert_equal(k_mem_slab_num_free_get(&kmslab), BLK_NUM);
}

/**
 * @brief Verify alloc and free of blocks from mem_slab
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_alloc_free_thread)
{

	tmslab_alloc_free(&mslab);
}

/**
 * @brief Allocate memory blocks and check for alignment of 8 bytes
 *
 * @details Allocate 3 blocks of memory from 2 memory slabs
 * respectively and check if all blocks are aligned to 8 bytes
 * and free them.
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_alloc_align)
{
	tmslab_alloc_align(&mslab);
	tmslab_alloc_align(&kmslab);
}

/**
 * @brief Verify allocation of memory blocks with timeouts
 *
 * @details Allocate 3 memory blocks from memory slab. Check
 * allocation of another memory block with NO_WAIT set, since
 * there are no blocks left to allocate in the memory slab,
 * the allocation fails with return value -ENOMEM. Then the
 * system up time is obtained, memory block allocation is
 * tried with timeout of 2000 ms. Now the allocation API
 * returns -EAGAIN as the waiting period is timeout. The
 * test case also checks if timeout has really happened by
 * checking delta period between the allocation request
 * was made and return of -EAGAIN.
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_alloc_timeout)
{
	if (arch_num_cpus() != 1) {
		ztest_test_skip();
	}

	tmslab_alloc_timeout(&mslab);
}

/**
 * @brief Verify count of allocated blocks
 *
 * @details The test case allocates 3 blocks one after the
 * other by checking for used block and free blocks in the
 * memory slab - mslab. Once all 3 blocks are allocated,
 * one more block is tried to allocates, which fails with
 * return value -ENOMEM. It also checks the allocation with
 * timeout. Again checks for used block and free blocks
 * number using @see k_mem_slab_num_used_get() and
 * @see k_mem_slab_num_free_get().
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_used_get)
{
	tmslab_used_get(&mslab);
	tmslab_used_get(&kmslab);
}

/**
 * @brief Verify pending of allocating blocks
 *
 * @details First, helper thread got all memory blocks,
 * and there is no free block left. k_mem_slab_alloc() with
 * time out will fail and return -EAGAIN.
 * Then k_mem_slab_alloc() without timeout tries to wait for
 * a memory block until helper thread free one.
 *
 * @ingroup kernel_memory_slab_tests
 */
ZTEST(mslab_api, test_mslab_pending)
{
	if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
		ztest_test_skip();
		return;
	}

	int ret_value;
	void *b;                        /* Pointer to memory block */

	(void)k_thread_create(&HELPER, stack, STACKSIZE,
			helper_thread, NULL, NULL, NULL,
			7, 0, K_NO_WAIT);

	k_sem_give(&SEM_REGRESSDONE);   /* Allow helper thread to run */

	k_sem_take(&SEM_HELPERDONE, K_FOREVER);		/* Wait for helper thread to finish */

	ret_value = k_mem_slab_alloc(&kmslab, &b, K_MSEC(20));
	zassert_equal(-EAGAIN, ret_value,
		      "Failed k_mem_slab_alloc, retValue %d\n", ret_value);

	k_sem_give(&SEM_REGRESSDONE);

	/* Wait for helper thread to free a block */

	ret_value = k_mem_slab_alloc(&kmslab, &b, K_FOREVER);
	zassert_equal(0, ret_value,
		      "Failed k_mem_slab_alloc, ret_value %d\n", ret_value);

	k_sem_give(&SEM_REGRESSDONE);

	/* Wait for helper thread to complete */
	k_sem_take(&SEM_HELPERDONE, K_FOREVER);

	/* Free memory block */
	k_mem_slab_free(&kmslab, b);
}
