/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <stdlib.h>
#include "pico/util/pheap.h"

pheap_t *ph_create(uint max_nodes, pheap_comparator comparator, void *user_data) {
    invalid_params_if(PHEAP, !max_nodes || max_nodes >= (1u << sizeof(pheap_node_id_t)));
    pheap_t *heap = calloc(1, sizeof(pheap_t));
    heap->max_nodes = max_nodes;
    heap->comparator = comparator;
    heap->nodes = calloc(max_nodes, sizeof(pheap_node_t));
    heap->user_data = user_data;
    ph_clear(heap);
    return heap;
}

void ph_clear(pheap_t *heap) {
    heap->root_id = 0;
    heap->free_head_id = 1;
    heap->free_tail_id = heap->max_nodes;
    for(uint i = 1; i < heap->max_nodes; i++) {
        ph_get_node(heap, i)->sibling = i + 1;
    }
    ph_get_node(heap, heap->max_nodes)->sibling = 0;
}

void ph_destroy(pheap_t *heap) {
    free(heap->nodes);
    free(heap);
}

pheap_node_id_t ph_merge_two_pass(pheap_t *heap, pheap_node_id_t id) {
    if (!id || !ph_get_node(heap, id)->sibling) {
        return id;
    } else {
        pheap_node_id_t a, b, new_node;
        a = id;
        b = ph_get_node(heap, id)->sibling;
        new_node = ph_get_node(heap, b)->sibling;
        ph_get_node(heap, a)->sibling = ph_get_node(heap, b)->sibling = 0;
        return ph_merge_nodes(heap, ph_merge_nodes(heap, a, b), ph_merge_two_pass(heap, new_node));
    }
}

static pheap_node_id_t ph_remove_any_head(pheap_t *heap, pheap_node_id_t root_id, bool reserve) {
    assert(root_id);
//    printf("Removing head %d (parent %d sibling %d)\n", root_id, ph_get_node(heap, root_id)->parent, ph_get_node(heap, root_id)->sibling);
    assert(!ph_get_node(heap, root_id)->sibling);
    assert(!ph_get_node(heap, root_id)->parent);
    pheap_node_id_t new_root_id = ph_merge_two_pass(heap, ph_get_node(heap, root_id)->child);
    if (!reserve) {
        if (heap->free_tail_id) {
            ph_get_node(heap, heap->free_tail_id)->sibling = root_id;
        }
        heap->free_tail_id = root_id;
    }
    if (new_root_id) ph_get_node(heap, new_root_id)->parent = 0;
    ph_get_node(heap, root_id)->sibling = 0;
    return new_root_id;
}

pheap_node_id_t ph_remove_head_reserve(pheap_t *heap, bool reserve) {
    pheap_node_id_t old_root_id = ph_peek_head(heap);
    heap->root_id = ph_remove_any_head(heap, old_root_id, reserve);
    return old_root_id;
}

#include <stdio.h>
bool ph_delete(pheap_t *heap, pheap_node_id_t id) {
    // 1) trivial cases
    if (!id) return false;
    if (id == heap->root_id) {
        ph_remove_head(heap);
        return true;
    }
    // 2) unlink the node from the tree
    pheap_node_t *node = ph_get_node(heap, id);
    if (!node->parent) return false; // not in tree
    pheap_node_t *parent = ph_get_node(heap, node->parent);
    if (parent->child == id) {
        parent->child = node->sibling;
    } else {
        pheap_node_id_t prev_sibling_id = parent->child;
        bool __unused found = false;
        do {
            pheap_node_t *prev_sibling = ph_get_node(heap, prev_sibling_id);
            if (prev_sibling->sibling == id) {
                prev_sibling->sibling = node->sibling;
                found = true;
                break;
            }
            prev_sibling_id = prev_sibling->sibling;
        } while (prev_sibling_id);
        assert(found);
    }
    node->sibling = node->parent = 0;
//    ph_dump(heap, NULL, NULL);
    // 3) remove it from the head of its own subtree
    pheap_node_id_t new_sub_tree = ph_remove_any_head(heap, id, false);
    assert(new_sub_tree != heap->root_id);
    heap->root_id = ph_merge_nodes(heap, heap->root_id, new_sub_tree);
    return true;
}

static uint ph_dump_node(pheap_t *heap, pheap_node_id_t id, void (*dump_key)(pheap_node_id_t, void *), void *user_data, uint indent) {
    uint count = 0;
    if (id) {
        count++;
        for (uint i = 0; i < indent * 2; i++) {
            putchar(' ');
        }
        pheap_node_t *node = ph_get_node(heap, id);
        printf("%d (c=%d s=%d p=%d) ", id, node->child, node->sibling, node->parent);
        if (dump_key) dump_key(id, user_data);
        printf("\n");
        count += ph_dump_node(heap, node->child, dump_key, user_data, indent + 1);
        count += ph_dump_node(heap, node->sibling, dump_key, user_data, indent);
    }
    return count;
}

void ph_dump(pheap_t *heap, void (*dump_key)(pheap_node_id_t, void *), void *user_data) {
    uint count = ph_dump_node(heap, heap->root_id, dump_key, user_data, 0);
    printf("node_count %d\n", count);
}