"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchGraph = void 0;
const GRAPH_DEFAULT_EVENTS_1 = require("../../constant/GRAPH_DEFAULT_EVENTS");
const spec_1 = require("../../spec/util/spec");
const f_1 = require("../../system/core/object/ForEachKeyValue/f");
const callAll_1 = require("../../util/call/callAll");
const callAllDict_1 = require("../../util/call/callAllDict");
const watchGraphUnit_1 = require("../watchGraphUnit");
const watchPin_1 = require("../watchPin");
const watchUnitIO_1 = require("../watchUnitIO");
function watchGraph(graph, callback, events = GRAPH_DEFAULT_EVENTS_1.GRAPH_DEFAULT_EVENTS) {
    const _unit_unlisten = {};
    const _merge_unlisten = {};
    const _watchUnit = (unit, unitId) => {
        const unitIOUnlisten = (0, watchUnitIO_1.watchUnitIO)(unit, events, ({ type, event, data }) => {
            callback({
                type,
                event,
                data: Object.assign(Object.assign({}, data), { unitId }),
            });
        });
        // if (unit instanceof Graph) {
        const unitGraphUnlisten = (0, watchGraphUnit_1.watchGraphUnit)(unit, events, ({ type, event, data }) => {
            callback({
                type,
                event,
                data: Object.assign(Object.assign({}, data), { unitId }),
            });
        });
        // }
        _unit_unlisten[unitId] = (0, callAll_1.callAll)([unitIOUnlisten, unitGraphUnlisten]);
    };
    const _watchMerge = (merge, mergeId) => {
        const mergeInputNodeId = (0, spec_1.getMergePinNodeId)(mergeId, 'input');
        const input = merge.getInput(mergeInputNodeId);
        const unlisten = (0, watchPin_1.watchPin)('merge', mergeId, input, ({ type, event, data }) => {
            callback({
                type,
                event,
                data: Object.assign(Object.assign({}, data), { mergeId }),
            });
        });
        _merge_unlisten[mergeId] = unlisten;
    };
    const addUnitListener = (id, unit, path) => {
        if (path.length === 0) {
            _watchUnit(unit, id);
        }
    };
    const cloneUnitListener = (id, newUnitId, newUnit, path) => {
        if (path.length === 0) {
            _watchUnit(newUnit, newUnitId);
        }
    };
    const addMergeListener = (id, mergeSpec, merge, path) => {
        if (path.length === 0) {
            _watchMerge(merge, id);
        }
    };
    const removeUnitListener = (unitId, unit, path) => {
        if (path.length === 0) {
            const unlisten = _unit_unlisten[unitId];
            unlisten();
            delete _unit_unlisten[unitId];
        }
    };
    const removeMergeListener = (mergeId, mergeSpec, merge, path) => {
        if (path.length === 0) {
            const unlisten = _merge_unlisten[mergeId];
            unlisten();
            delete _merge_unlisten[mergeId];
        }
    };
    const units = graph.getUnits();
    const merges = graph.getMerges();
    (0, f_1.default)(units, _watchUnit);
    (0, f_1.default)(merges, _watchMerge);
    graph.addListener('before_add_unit', addUnitListener);
    graph.addListener('clone_unit', cloneUnitListener);
    graph.addListener('before_add_merge', addMergeListener);
    graph.addListener('before_remove_unit', removeUnitListener);
    graph.addListener('before_remove_merge', removeMergeListener);
    return () => {
        graph.removeListener('before_add_unit', addUnitListener);
        graph.removeListener('clone_unit', cloneUnitListener);
        graph.removeListener('before_add_merge', addMergeListener);
        graph.removeListener('before_remove_unit', removeUnitListener);
        graph.removeListener('before_remove_merge', removeMergeListener);
        (0, callAllDict_1.callAllDict)(_unit_unlisten)();
        (0, callAllDict_1.callAllDict)(_merge_unlisten)();
    };
}
exports.watchGraph = watchGraph;
//# sourceMappingURL=watchGraph.js.map