/*
 * VMware VMCI Driver
 *
 * Copyright (C) 2012 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <linux/slab.h>
#include "vmci_handle_array.h"

static size_t handle_arr_calc_size(u32 capacity)
{
	return VMCI_HANDLE_ARRAY_HEADER_SIZE +
	    capacity * sizeof(struct vmci_handle);
}

struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity)
{
	struct vmci_handle_arr *array;

	if (max_capacity == 0 || capacity > max_capacity)
		return NULL;

	if (capacity == 0)
		capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY,
			       max_capacity);

	array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC);
	if (!array)
		return NULL;

	array->capacity = capacity;
	array->max_capacity = max_capacity;
	array->size = 0;

	return array;
}

void vmci_handle_arr_destroy(struct vmci_handle_arr *array)
{
	kfree(array);
}

int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
				 struct vmci_handle handle)
{
	struct vmci_handle_arr *array = *array_ptr;

	if (unlikely(array->size >= array->capacity)) {
		/* reallocate. */
		struct vmci_handle_arr *new_array;
		u32 capacity_bump = min(array->max_capacity - array->capacity,
					array->capacity);
		size_t new_size = handle_arr_calc_size(array->capacity +
						       capacity_bump);

		if (array->size >= array->max_capacity)
			return VMCI_ERROR_NO_MEM;

		new_array = krealloc(array, new_size, GFP_ATOMIC);
		if (!new_array)
			return VMCI_ERROR_NO_MEM;

		new_array->capacity += capacity_bump;
		*array_ptr = array = new_array;
	}

	array->entries[array->size] = handle;
	array->size++;

	return VMCI_SUCCESS;
}

/*
 * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.
 */
struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array,
						struct vmci_handle entry_handle)
{
	struct vmci_handle handle = VMCI_INVALID_HANDLE;
	u32 i;

	for (i = 0; i < array->size; i++) {
		if (vmci_handle_is_equal(array->entries[i], entry_handle)) {
			handle = array->entries[i];
			array->size--;
			array->entries[i] = array->entries[array->size];
			array->entries[array->size] = VMCI_INVALID_HANDLE;
			break;
		}
	}

	return handle;
}

/*
 * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.
 */
struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array)
{
	struct vmci_handle handle = VMCI_INVALID_HANDLE;

	if (array->size) {
		array->size--;
		handle = array->entries[array->size];
		array->entries[array->size] = VMCI_INVALID_HANDLE;
	}

	return handle;
}

/*
 * Handle at given index, VMCI_INVALID_HANDLE if invalid index.
 */
struct vmci_handle
vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index)
{
	if (unlikely(index >= array->size))
		return VMCI_INVALID_HANDLE;

	return array->entries[index];
}

bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array,
			       struct vmci_handle entry_handle)
{
	u32 i;

	for (i = 0; i < array->size; i++)
		if (vmci_handle_is_equal(array->entries[i], entry_handle))
			return true;

	return false;
}

/*
 * NULL if the array is empty. Otherwise, a pointer to the array
 * of VMCI handles in the handle array.
 */
struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array)
{
	if (array->size)
		return array->entries;

	return NULL;
}
