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

#include <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;

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

	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((u32_t)block[i] % BLK_ALIGN == 0, NULL);
	}
	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;
	s64_t tms;

	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);
	/** TESTPOINT: -EAGAIN Waiting period timed out*/
	tms = k_uptime_get();
	zassert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN,
		      NULL);
	/**
	 * TESTPOINT: timeout Maximum time to wait for operation to
	 * complete (in milliseconds)
	 */
	zassert_true(k_uptime_delta(&tms) >= TIMEOUT, NULL);

	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, NULL);
		/**
		 * TESTPOINT: Get the number of unused blocks in a memory slab.
		 */
		zassert_equal(k_mem_slab_num_free_get(pslab), BLK_NUM - 1 - i, NULL);
	}

	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, NULL);
	/* used get on allocation failure*/
	zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM, NULL);

	zassert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN,
		      NULL);
	zassert_equal(k_mem_slab_num_free_get(pslab), 0, NULL);
	zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM, NULL);

	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, NULL);
		zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM - 1 - i, NULL);
	}
}

/*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
 */
void test_mslab_kinit(void)
{
	k_mem_slab_init(&mslab, tslab, BLK_SIZE, BLK_NUM);
	zassert_equal(k_mem_slab_num_used_get(&mslab), 0, NULL);
	zassert_equal(k_mem_slab_num_free_get(&mslab), BLK_NUM, NULL);
}

/**
 * @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
 */
void test_mslab_kdefine(void)
{
	zassert_equal(k_mem_slab_num_used_get(&kmslab), 0, NULL);
	zassert_equal(k_mem_slab_num_free_get(&kmslab), BLK_NUM, NULL);
}

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

	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
 */
void test_mslab_alloc_align(void)
{
	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
 */
void test_mslab_alloc_timeout(void)
{
	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
 */
void test_mslab_used_get(void)
{
	tmslab_used_get(&mslab);
	tmslab_used_get(&kmslab);
}
