/* 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);

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)
{
	void *ptr = cb_malloc(TEST_HEAP_SZ);
	assert_ptr_equal(ptr, NULL);
}

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)
{
	void *ptr = cb_memalign(16, TEST_HEAP_SZ);
	assert_ptr_equal(ptr, NULL);
}

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);
}
