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

#include <ztest.h>
#include <zephyr/types.h>
#include <string.h>
#include <stdio.h>

struct parameter {
	struct parameter *next;
	const char *fn;
	const char *name;
	uintptr_t value;
};

#ifndef KERNEL

#include <stdlib.h>
#include <stdarg.h>

static void free_parameter(struct parameter *param)
{
	free(param);
}

static struct parameter *alloc_parameter(void)
{
	struct parameter *param;

	param = calloc(1, sizeof(struct parameter));
	if (!param) {
		PRINT("Failed to allocate mock parameter\n");
		ztest_test_fail();
	}

	return param;
}

void z_init_mock(void)
{
}

void printk(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	vprintf(fmt, ap);
	va_end(ap);
}

void vprintk(const char *fmt, va_list ap)
{
	vprintf(fmt, ap);
}
#else

/*
 * FIXME: move to sys_io.h once the argument signature for bitmap has
 * been fixed to void* or similar GH-2825
 */
#define BITS_PER_UL (8 * sizeof(unsigned long int))
#define DEFINE_BITFIELD(name, bits)                                            \
	unsigned long int(name)[((bits) + BITS_PER_UL - 1) / BITS_PER_UL]

static inline int sys_bitfield_find_first_clear(const unsigned long *bitmap,
						const unsigned int bits)
{
	const size_t words = (bits + BITS_PER_UL - 1) / BITS_PER_UL;
	size_t cnt;
	unsigned int long neg_bitmap;

	/*
	 * By bitwise negating the bitmap, we are actually implementing
	 * ffc (find first clear) using ffs (find first set).
	 */
	for (cnt = 0; cnt < words; cnt++) {
		neg_bitmap = ~bitmap[cnt];
		if (neg_bitmap == 0) {
			/* All full. Try next word. */
			continue;
		} else if (neg_bitmap == ~0UL) {
			/* First bit is free */
			return cnt * BITS_PER_UL;
		} else {
			const unsigned int bit = (cnt * BITS_PER_UL) +
						 __builtin_ffsl(neg_bitmap) - 1;
			/* Ensure first free bit is within total bits count */
			if (bit < bits) {
				return bit;
			} else {
				return -1;
			}
		}
	}
	return -1;
}

static DEFINE_BITFIELD(params_allocation, CONFIG_ZTEST_PARAMETER_COUNT);
static struct parameter params[CONFIG_ZTEST_PARAMETER_COUNT];

static void free_parameter(struct parameter *param)
{
	unsigned int allocation_index = param - params;

	if (param == NULL)
		return;
	__ASSERT(allocation_index < CONFIG_ZTEST_PARAMETER_COUNT,
		 "param %p given to free is not in the static buffer %p:%u",
		 param, params, CONFIG_ZTEST_PARAMETER_COUNT);
	sys_bitfield_clear_bit((mem_addr_t)params_allocation, allocation_index);
}

static struct parameter *alloc_parameter(void)
{
	int allocation_index;
	struct parameter *param;

	allocation_index = sys_bitfield_find_first_clear(
		params_allocation, CONFIG_ZTEST_PARAMETER_COUNT);
	if (allocation_index == -1) {
		printk("No more mock parameters available for allocation\n");
		ztest_test_fail();
	}
	sys_bitfield_set_bit((mem_addr_t)params_allocation, allocation_index);
	param = params + allocation_index;
	(void)memset(param, 0, sizeof(*param));
	return param;
}

void z_init_mock(void)
{
}

#endif

static struct parameter *find_and_delete_value(struct parameter *param,
					       const char *fn, const char *name)
{
	struct parameter *value;

	if (!param->next) {
		return NULL;
	}

	if (strcmp(param->next->name, name) || strcmp(param->next->fn, fn)) {
		return find_and_delete_value(param->next, fn, name);
	}

	value = param->next;
	param->next = param->next->next;
	value->next = NULL;

	return value;
}

static void insert_value(struct parameter *param, const char *fn,
			 const char *name, uintptr_t val)
{
	struct parameter *value;

	value = alloc_parameter();
	value->fn = fn;
	value->name = name;
	value->value = val;

	/* Seek to end of linked list to ensure correct discovery order in find_and_delete_value */
	while (param->next) {
		param = param->next;
	}

	/* Append to end of linked list */
	value->next = param->next;
	param->next = value;
}

static struct parameter parameter_list = { NULL, "", "", 0 };
static struct parameter return_value_list = { NULL, "", "", 0 };

void z_ztest_expect_value(const char *fn, const char *name, uintptr_t val)
{
	insert_value(&parameter_list, fn, name, val);
}

void z_ztest_check_expected_value(const char *fn, const char *name,
				  uintptr_t val)
{
	struct parameter *param;
	uintptr_t expected;

	param = find_and_delete_value(&parameter_list, fn, name);
	if (!param) {
		PRINT("Failed to find parameter %s for %s\n", name, fn);
		ztest_test_fail();
	}

	expected = param->value;
	free_parameter(param);

	if (expected != val) {
		/* We need to cast these values since the toolchain doesn't
		 * provide inttypes.h
		 */
		PRINT("%s:%s received wrong value: Got %lu, expected %lu\n", fn,
		      name, (unsigned long)val, (unsigned long)expected);
		ztest_test_fail();
	}
}

void z_ztest_expect_data(const char *fn, const char *name, void *val)
{
	insert_value(&parameter_list, fn, name, (uintptr_t)val);
}

void z_ztest_check_expected_data(const char *fn, const char *name, void *data,
				 uint32_t length)
{
	struct parameter *param;
	void *expected;

	param = find_and_delete_value(&parameter_list, fn, name);
	if (!param) {
		PRINT("Failed to find parameter %s for %s\n", name, fn);
		/* No return from this function but for coverity reasons
		 * put a return after to avoid the warning of a null
		 * dereference of param below.
		 */
		ztest_test_fail();
		return;
	}

	expected = (void *)param->value;
	free_parameter(param);

	if (expected == NULL && data != NULL) {
		PRINT("%s:%s received null pointer\n", fn, name);
		ztest_test_fail();
	} else if (data == NULL && expected != NULL) {
		PRINT("%s:%s received data while expected null pointer\n", fn,
		      name);
		ztest_test_fail();
	} else if (data != NULL) {
		if (memcmp(data, expected, length) != 0) {
			PRINT("%s:%s data provided don't match\n", fn, name);
			ztest_test_fail();
		}
	}
}

void z_ztest_return_data(const char *fn, const char *name, void *val)
{
	insert_value(&parameter_list, fn, name, (uintptr_t)val);
}

void z_ztest_copy_return_data(const char *fn, const char *name, void *data,
			      uint32_t length)
{
	struct parameter *param;
	void *return_data;

	if (data == NULL) {
		PRINT("%s:%s received null pointer\n", fn, name);
		ztest_test_fail();
		return;
	}

	param = find_and_delete_value(&parameter_list, fn, name);
	if (!param) {
		PRINT("Failed to find parameter %s for %s\n", name, fn);
		memset(data, 0, length);
		ztest_test_fail();
	} else {
		return_data = (void *)param->value;
		free_parameter(param);
		memcpy(data, return_data, length);
	}
}

void z_ztest_returns_value(const char *fn, uintptr_t value)
{
	insert_value(&return_value_list, fn, "", value);
}

uintptr_t z_ztest_get_return_value(const char *fn)
{
	uintptr_t value;
	struct parameter *param =
		find_and_delete_value(&return_value_list, fn, "");

	if (!param) {
		PRINT("Failed to find return value for function %s\n", fn);
		ztest_test_fail();
	}

	value = param->value;
	free_parameter(param);

	return value;
}

static void free_param_list(struct parameter *param)
{
	struct parameter *next;

	while (param) {
		next = param->next;
		free_parameter(param);
		param = next;
	}
}

int z_cleanup_mock(void)
{
	int fail = 0;

	if (parameter_list.next) {
		PRINT("Parameter not used by mock: %s:%s\n",
		      parameter_list.next->fn,
		      parameter_list.next->name);
		fail = 1;
	}
	if (return_value_list.next) {
		PRINT("Return value no used by mock: %s\n",
		      return_value_list.next->fn);
		fail = 2;
	}

	free_param_list(parameter_list.next);
	free_param_list(return_value_list.next);

	parameter_list.next = NULL;
	return_value_list.next = NULL;

	return fail;
}
