// import {Assert} from '../../utils/assert'
import { Stack } from 'stack-typescript';
import { IntPairMap } from '../../utils/IntPairMap';
var VertStatus;
(function (VertStatus) {
    VertStatus[VertStatus["NotVisited"] = 0] = "NotVisited";
    VertStatus[VertStatus["InStack"] = 1] = "InStack";
    VertStatus[VertStatus["Visited"] = 2] = "Visited";
})(VertStatus || (VertStatus = {}));
class StackStruct {
    constructor(v, i) {
        this.v = v;
        this.i = i;
    }
}
export class CycleRemoval {
    static getFeedbackSetWithConstraints(arg0, arg1) {
        throw new Error('Method not implemented.');
    }
    static push(stack, status, v, i) {
        status[v] = VertStatus.InStack;
        stack.push(new StackStruct(v, i));
    }
    static getFeedbackSet(graph) {
        const feedbackSet = new IntPairMap(graph.nodeCount);
        if (graph == null || graph.nodeCount == 0)
            return [];
        const status = new Array(graph.nodeCount).fill(VertStatus.NotVisited);
        for (let vertex = 0; vertex < graph.nodeCount; vertex++) {
            if (status[vertex] == VertStatus.Visited)
                continue;
            /*Assert.assert(status[vertex] != VertStatus.InStack)*/
            const stack = new Stack(); //avoiding the recursion
            let i = 0; //  the index in the outEnum
            CycleRemoval.push(stack, status, vertex, i);
            while (stack.size > 0) {
                const s = stack.pop();
                vertex = s.v;
                status[vertex] = VertStatus.Visited;
                i = s.i;
                let outEnum = graph.outEdges[vertex];
                for (; i < outEnum.length; i++) {
                    const e = outEnum[i];
                    if (e.source == e.target)
                        continue;
                    const targetStatus = status[e.target];
                    if (targetStatus == VertStatus.InStack) {
                        feedbackSet.set(e.source, e.target, e);
                    }
                    else if (targetStatus == VertStatus.NotVisited) {
                        //have to go deeper
                        CycleRemoval.push(stack, status, vertex, i + 1);
                        vertex = e.target;
                        status[e.target] = VertStatus.Visited;
                        outEnum = graph.outEdges[vertex];
                        i = -1;
                    }
                }
            }
        }
        return Array.from(feedbackSet.values());
    }
}
//# sourceMappingURL=CycleRemoval.js.map