import { alg, Graph } from 'graphlib';
import { transformGraphicModelToStedModel } from './sted-transformer';
export class StedProcessCycles {
    constructor() { }
    generateGraph(stedNodeList) {
        var generatedGraph = new Graph({ directed: true, multigraph: true });
        stedNodeList.forEach(stedNode => {
            generatedGraph.setNode(stedNode.name, stedNode.name);
            stedNode.outlets.forEach(out => generatedGraph.setEdge(stedNode.name, out.dstNode, `${stedNode.name}-${out.name}-${out.dstNode}`, out.name));
        });
        return generatedGraph;
    }
    findAllCycles(stedNodes) {
        let referenceGraph = this.generateGraph(stedNodes);
        let edges = {};
        referenceGraph.nodes().forEach(node => {
            edges[node] = referenceGraph.successors(node) || [];
        });
        const findCycle = require('find-cycle/directed');
        const getConnectedNodes = node => referenceGraph.successors(node) || [];
        var resultCycles = [];
        let cycle = [];
        do {
            cycle = findCycle(referenceGraph.nodes(), getConnectedNodes);
            if (cycle) {
                resultCycles.push(cycle);
                const cycleNodeEdges = referenceGraph.nodeEdges(cycle[0], cycle[1]);
                if (cycleNodeEdges) {
                    cycleNodeEdges.forEach(edge => {
                        referenceGraph.removeEdge(cycle[0], cycle[1], edge.name);
                    });
                }
            }
        } while (cycle);
        return resultCycles;
    }
    findCycles(stedNodes) {
        let reorderedCycles = [];
        // transform its own json graph to graphlib graph
        let genGraph = this.generateGraph(stedNodes);
        // find cycles
        let cycles = this.findAllCycles(stedNodes);
        cycles.forEach((cycle, idx) => {
            let preOrderResult = [];
            preOrderResult = alg.preorder(genGraph, cycle);
            preOrderResult = preOrderResult.filter(item => cycle.includes(item));
            reorderedCycles[idx] = preOrderResult;
        });
        return reorderedCycles;
    }
    run(model) {
        let transformedNodes = transformGraphicModelToStedModel(model);
        let cycles = this.findCycles(transformedNodes);
        return cycles;
    }
}
//# sourceMappingURL=sted-process-cycles.js.map