// SPDX-License-Identifier: GPL-2.0+
/*
 * Handles a contiguous list of pointers which be allocated and freed
 *
 * Copyright 2023 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <alist.h>
#include <display_options.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>

enum {
	ALIST_INITIAL_SIZE	= 4,	/* default size of unsized list */
};

bool alist_init(struct alist *lst, uint obj_size, uint start_size)
{
	/* Avoid realloc for the initial size to help malloc_simple */
	memset(lst, '\0', sizeof(struct alist));
	if (start_size) {
		lst->data = calloc(obj_size, start_size);
		if (!lst->data) {
			lst->flags = ALISTF_FAIL;
			return false;
		}
		lst->alloc = start_size;
	}
	lst->obj_size = obj_size;

	return true;
}

void alist_uninit(struct alist *lst)
{
	free(lst->data);

	/* Clear fields to avoid any confusion */
	memset(lst, '\0', sizeof(struct alist));
}

void alist_empty(struct alist *lst)
{
	lst->count = 0;
}

/**
 * alist_expand_to() - Expand a list to the given size
 *
 * @lst: List to modify
 * @inc_by: Amount to expand to
 * Return: true if OK, false if out of memory
 */
static bool alist_expand_to(struct alist *lst, uint new_alloc)
{
	void *new_data;

	if (lst->flags & ALISTF_FAIL)
		return false;

	/* avoid using realloc() since it increases code size */
	new_data = malloc(lst->obj_size * new_alloc);
	if (!new_data) {
		lst->flags |= ALISTF_FAIL;
		return false;
	}

	memcpy(new_data, lst->data, lst->obj_size * lst->alloc);
	free(lst->data);

	memset(new_data + lst->obj_size * lst->alloc, '\0',
	       lst->obj_size * (new_alloc - lst->alloc));
	lst->alloc = new_alloc;
	lst->data = new_data;

	return true;
}

bool alist_expand_by(struct alist *lst, uint inc_by)
{
	return alist_expand_to(lst, lst->alloc + inc_by);
}

/**
 * alist_expand_min() - Expand to at least the provided size
 *
 * Expands to the lowest power of two which can incorporate the new size
 *
 * @lst: alist to expand
 * @min_alloc: Minimum new allocated size; if 0 then ALIST_INITIAL_SIZE is used
 * Return: true if OK, false if out of memory
 */
static bool alist_expand_min(struct alist *lst, uint min_alloc)
{
	uint new_alloc;

	for (new_alloc = lst->alloc ?: ALIST_INITIAL_SIZE;
	     new_alloc < min_alloc;)
		new_alloc *= 2;

	return alist_expand_to(lst, new_alloc);
}

const void *alist_get_ptr(const struct alist *lst, uint index)
{
	if (index >= lst->count)
		return NULL;

	return lst->data + index * lst->obj_size;
}

int alist_calc_index(const struct alist *lst, const void *ptr)
{
	uint index;

	if (!lst->count || ptr < lst->data)
		return -1;

	index = (ptr - lst->data) / lst->obj_size;

	return index;
}

bool alist_chk_ptr(const struct alist *lst, const void *ptr)
{
	int index = alist_calc_index(lst, ptr);

	return index >= 0 && index < lst->count;
}

const void *alist_next_ptrd(const struct alist *lst, const void *ptr)
{
	int index = alist_calc_index(lst, ptr);

	assert(index != -1);

	return alist_get_ptr(lst, index + 1);
}

void *alist_ensure_ptr(struct alist *lst, uint index)
{
	uint minsize = index + 1;
	void *ptr;

	if (index >= lst->alloc && !alist_expand_min(lst, minsize))
		return NULL;

	ptr = lst->data + index * lst->obj_size;
	if (minsize >= lst->count)
		lst->count = minsize;

	return ptr;
}

void *alist_add_placeholder(struct alist *lst)
{
	return alist_ensure_ptr(lst, lst->count);
}

void *alist_add_ptr(struct alist *lst, void *obj)
{
	void *ptr;

	ptr = alist_add_placeholder(lst);
	if (!ptr)
		return NULL;
	memcpy(ptr, obj, lst->obj_size);

	return ptr;
}

void *alist_uninit_move_ptr(struct alist *alist, size_t *countp)
{
	void *ptr;

	if (countp)
		*countp = alist->count;
	if (!alist->count) {
		alist_uninit(alist);
		return NULL;
	}

	ptr = alist->data;

	/* Clear everything out so there is no record of the data */
	alist_init(alist, alist->obj_size, 0);

	return ptr;
}
