#include "kheap.h"
#include "log.h"

static void swap_entries(struct heap_entry *a, struct heap_entry *b)
{
	// Static to not waste stack space, NOT thread safe
	static struct heap_entry tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

int heap_parent(int i)
{
	return (i - 1) / 2;
}

int heap_left(int i)
{
	return 2 * i + 1;
}

int heap_right(int i)
{
	return 2 * i + 2;
}

static void heap_sort(struct min_heap *heap, int i)
{
	int l = heap_left(i), r = heap_right(i);
	int smallest = i;
	int size = heap->size;
	struct heap_entry *e = heap->elements;

	if (l < size && e[l].key < e[smallest].key)
		smallest = l;
	if (r < size && e[r].key < e[smallest].key)
		smallest = r;

	if (smallest != i)
	{
		swap_entries(&e[i], &e[smallest]);
		heap_sort(heap, smallest);
	}
}

static void heap_delete_root(struct min_heap *heap)
{
	if (heap->size <= 0)
		return;
	if (heap->size == 1)
		heap->size--;

	heap->elements[0] = heap->elements[--heap->size];
	heap_sort(heap, 0);
}

void heap_decrease(struct min_heap *heap, int i, struct heap_entry to)
{
	heap->elements[i] = to;
	int k = to.key;

	while (i && heap->elements[heap_parent(i)].key > k)
	{
		swap_entries(&heap->elements[i], &heap->elements[heap_parent(i)]);
		i = heap_parent(i);
	}
}

void heap_delete(struct min_heap *heap, int i)
{
	heap_decrease(heap, i,
				  (struct heap_entry){
					  .key = -1,
					  .address = 0,
				  });
	heap_delete_root(heap);
}

void heap_insert(struct min_heap *heap, struct heap_entry e)
{
	kassert(heap->size < HEAP_SIZE, "Heap overflow!");

	int i = heap->size++;
	uint k = e.key;
	heap->elements[i] = e;

	// While the parent element is GREATER than the child
	while (i && heap->elements[heap_parent(i)].key > k)
	{
		swap_entries(&heap->elements[i], &heap->elements[heap_parent(i)]);
		i = heap_parent(i);
	}
}

struct heap_entry heap_lookup_min(struct min_heap *heap, int min, bool *ok,
								  bool delete, int *i)
{
	int j = 0;
	struct heap_entry *e = heap->elements;

	while (j < heap->size && e[j].key < min)
	{
		int left = heap_left(j), right = heap_right(j);

		// If left is invalid, use right, if right is invalid, use left.
		// If both are valid, chose the smallest one.
		// In the first case, right may too be invalid, but it will be
		// sorted out in the while loop (see else clause at end of function).

		if (left >= heap->size)
			j = right;
		else if (right >= heap->size)
			j = left;
		else
			j = e[left].key < e[right].key ? left : right;
	}

	if (j < heap->size)
	{
		struct heap_entry val = e[j];

		*ok = true;

		if (i)
			*i = j;

		if (delete)
			heap_delete(heap, j);

		return val;
	}
	else
	{
		*ok = false;
		return (struct heap_entry){0};
	}
}

static int heap_entry_index(struct min_heap *heap, struct heap_entry e)
{
	size_t key = e.key;
	int i = 0;

	struct heap_entry *a = heap->elements;

	while (i < heap->size && a[i].key != key)
	{
		int left = heap_left(i),
			right = heap_right(i);

		if (left >= heap->size)
			i = right;
		else if (right >= heap->size)
			i = left;
		else
			i = a[left].key < a[right].key ? left : right;
	}

	if (i >= heap->size)
		return -1;
	else
		return i;
}

void heap_decrease_entry(struct min_heap *heap, struct heap_entry from,
						 struct heap_entry to)
{
	heap_decrease(heap, heap_entry_index(heap, from), to);
}

void heap_delete_entry(struct min_heap *heap, struct heap_entry e)
{
	heap_delete(heap, heap_entry_index(heap, e));
}
