import BinaryHeap from "../collection/heap/BinaryHeap.js";
import { mn_graph_collapse_weighted_edge } from "./mn_graph_collapse_weighted_edge.js";
import { WeightedEdge } from "./WeightedEdge.js";

/**
 * Reduce number of nodes in the graph by collapsing edges and joining neighbouring nodes
 * Simplifies a graph, reducing number of edges and nodes
 * @template T
 * @param {Graph<MultiNode<T>>} graph
 * @param {number} max_node_limit Maximum number of "source" nodes per joined node
 */
export function mn_graph_coarsen(graph, max_node_limit) {

    /**
     *
     * @type {BinaryHeap<WeightedEdge>}
     */
    const open_set = new BinaryHeap(WeightedEdge.extractNegativeWeight);

    // add all edges to the heap
    const edges = graph.getEdges();

    for (let edge of edges) {
        open_set.push(edge);
    }

    while (!open_set.isEmpty()) {
        const edge = open_set.pop();

        // attempt collapse of the heaviest edge
        const collapsed = mn_graph_collapse_weighted_edge(graph, edge, max_node_limit, open_set);

        if(!collapsed){
            throw new Error(`Failed to collapse edge ${edge}`);
        }
    }
}
