/* SPDX-License-Identifier: GPL-2.0-only */

/* Include malloc() and memalign() source code and alter its name to indicate the functions
   source origin. */
#define calloc cb_calloc
#define malloc cb_malloc
#define free cb_free
#define memalign cb_memalign
#undef __noreturn
#define __noreturn

#include "../lib/malloc.c"

#undef calloc
#undef malloc
#undef free
#undef memalign
#undef __noreturn
#define __noreturn __attribute__((noreturn))

#include <stdlib.h>
#include <tests/test.h>
#include <commonlib/helpers.h>
#include <types.h>
#include <symbols.h>

/* 4 MiB */
#define TEST_HEAP_SZ 0x400000

/* Heap region setup */
__weak extern uint8_t _test_heap[];
__weak extern uint8_t _etest_heap[];
TEST_REGION(test_heap, TEST_HEAP_SZ);
TEST_SYMBOL(_heap, _test_heap);
TEST_SYMBOL(_eheap, _etest_heap);

void die(const char *msg, ...)
{
	function_called();
}

static int setup_test(void **state)
{
	free_mem_ptr = &_heap;
	free_mem_end_ptr = &_eheap;
	free_last_alloc_ptr = &_heap;

	return 0;
}

static int setup_calloc_test(void **state)
{
	memset(_test_heap, 0xFF, TEST_HEAP_SZ);
	return setup_test(state);
}

static void test_malloc_out_of_memory(void **state)
{
	/* Expect die() call if out of memory */
	expect_function_call(die);
	cb_malloc(TEST_HEAP_SZ);
}

static void test_malloc_zero(void **state)
{
	void *ptr1 = cb_malloc(0);
	void *ptr2 = cb_malloc(0);
	void *ptr3 = cb_malloc(0);

	/* Expect malloc(0) to return the same pointer as there are no bytes
	   to be added to the heap */
	assert_ptr_equal(ptr1, ptr2);
	assert_ptr_equal(ptr2, ptr3);
}

static void test_malloc_multiple_small_allocations(void **state)
{
	/* Make multiple small allocations (smaller than alignment)
	   Expect no call to die(), as this allocations should be small
	   enough to fit in provided memory */
	void *prev;
	void *curr = cb_malloc(3);
	assert_non_null(curr);
	for (int i = 0; i < 1000; ++i) {
		prev = curr;
		curr = cb_malloc(3);
		assert_non_null(curr);
		assert_true(prev < curr);
	}
}

static void test_memalign_different_alignments(void **state)
{
	void *ptr1 = cb_memalign(4, 30);
	void *ptr2 = cb_memalign(16, 22);
	void *ptr3 = cb_memalign(8, 64);

	assert_true((uintptr_t)ptr1 % 4 == 0);
	assert_true((uintptr_t)ptr2 % 16 == 0);
	assert_true((uintptr_t)ptr3 % 8 == 0);
}

static void test_memalign_out_of_memory(void **state)
{
	expect_function_call(die);
	cb_memalign(16, TEST_HEAP_SZ);
}

static void test_memalign_zero(void **state)
{
	void *ptr1 = cb_memalign(16, 0);
	void *ptr2 = cb_memalign(7, 0);
	void *ptr3 = cb_memalign(11, 0);

	/* Expect memalign(x, 0) to return the same pointer as there are no bytes
	   to be added to the heap */
	assert_ptr_equal(ptr1, ptr2);
	assert_ptr_equal(ptr2, ptr3);
}

static void test_memalign_multiple_small_allocations(void **state)
{
	/* Make multiple small allocations (smaller than alignment)
	   Expect no call to die(), as this allocations should be small
	   enough to fit in provided memory. There should also be no error
	   when allocating memory with different align values. */
	void *prev;
	void *curr = cb_memalign(3, 3);
	assert_non_null(curr);
	for (int i = 0; i < 1000; ++i) {
		/* Expect new pointer larger than previously allocated and aligned to provided
		   value. Alignment has to be power of 2 to be applied correctly. */
		prev = curr;
		curr = cb_memalign(2u << (i % 6), 3);
		assert_non_null(curr);
		assert_true(prev < curr);
		assert_true((uintptr_t)curr % (2u << (i % 6)) == 0);
	}
}

static void test_calloc_memory_is_zeroed(void **state)
{
	const size_t nitems = 42;
	const size_t size = sizeof(uint32_t);
	void *ptr = cb_calloc(nitems, size);
	assert_non_null(ptr);

	for (size_t i = 0; i < nitems; i++) {
		const uint32_t *p = (const uint32_t *)ptr + i;
		assert_int_equal(*p, 0);
	}
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test_setup(test_malloc_out_of_memory, setup_test),
		cmocka_unit_test_setup(test_malloc_zero, setup_test),
		cmocka_unit_test_setup(test_malloc_multiple_small_allocations, setup_test),
		cmocka_unit_test_setup(test_memalign_different_alignments, setup_test),
		cmocka_unit_test_setup(test_memalign_out_of_memory, setup_test),
		cmocka_unit_test_setup(test_memalign_zero, setup_test),
		cmocka_unit_test_setup(test_memalign_multiple_small_allocations, setup_test),
		cmocka_unit_test_setup(test_calloc_memory_is_zeroed, setup_calloc_test),
	};

	return cb_run_group_tests(tests, NULL, NULL);
}
