"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncG = exports.AsyncGRef = exports.AsyncGWatch = exports.AsyncGCall = exports.AsyncGGet = void 0;
const watchGraph_1 = require("../../../debug/graph/watchGraph");
const watchUnit_1 = require("../../../debug/watchUnit");
const evaluate_1 = require("../../../spec/evaluate");
const stringify_1 = require("../../../spec/stringify");
const stringifySpec_1 = require("../../../spec/stringifySpec");
const f_1 = require("../../../system/core/object/ForEachKeyValue/f");
const clone_1 = require("../../../util/clone");
const stringifyPinData_1 = require("../../stringifyPinData");
const Async_1 = require("./Async");
function _call(graph, method, fork, bubble, ...args) {
    const { global } = graph.__system;
    let result;
    if (fork) {
        result = graph[method].call(graph, ...args, fork, bubble);
    }
    else {
        const all = global.graph[graph.id];
        for (const globalId in all) {
            const sibling = all[globalId];
            result = sibling[method].call(sibling, ...args, fork, bubble);
        }
    }
    return result;
}
const AsyncGGet = (graph) => {
    const obj = {
        $getBundle({ deep }, callback) {
            const bundle = graph.getBundleSpec(deep);
            const { spec } = bundle;
            (0, stringifySpec_1.stringifyGraphSpecData)(spec);
            callback(bundle);
        },
        $getUnitPinData({ unitId, type, pinId }, callback) {
            const state = graph.getUnitData(unitId, type, pinId);
            callback(state);
        },
        $getGraphData(data, callback) {
            const children = graph.getGraphChildren();
            const err = graph.getGraphErr();
            const units = graph.getUnits();
            const pinData = {};
            (0, f_1.default)(units, (unit, unitId) => {
                const unitPinData = unit.getPinsData();
                const _unitPinData = (0, stringifyPinData_1.stringifyPinData)(unitPinData);
                pinData[unitId] = _unitPinData;
            });
            const _mergeData = graph.getGraphMergeInputData();
            const mergeData = {};
            for (const mergeId in _mergeData) {
                const data = _mergeData[mergeId];
                Performance;
                if (data === undefined) {
                    mergeData[mergeId] = undefined;
                }
                else {
                    mergeData[mergeId] = (0, stringify_1.stringify)(data);
                }
            }
            callback({ children, err, pinData, mergeData });
        },
        async $snapshot(data, callback) {
            const memory = graph.snapshot();
            callback(memory);
        },
        $snapshotUnit({ unitId }, callback) {
            const unit = graph.getUnit(unitId);
            const memory = unit.snapshot();
            (0, stringifySpec_1.stringifyMemorySpecData)(memory);
            callback(memory);
        },
        $getGraphChildren({}, callback) {
            const children = graph.getGraphChildren();
            callback(children);
        },
        $getGraphErr({}, callback) {
            const state = graph.getGraphErr();
            callback(state);
        },
        $getGraphPinData({}, callback) {
            const pinData = {};
            const units = graph.getUnits();
            (0, f_1.default)(units, (unit, unitId) => {
                const unitPinData = unit.getPinsData();
                const _unitPinData = (0, stringifyPinData_1.stringifyPinData)(unitPinData, true);
                pinData[unitId] = _unitPinData;
            });
            callback(pinData);
        },
        $getGraphMergeInputData({}, callback) {
            const mergeData = graph.getGraphMergeInputData();
            const _mergeData = (0, stringifyPinData_1.stringifyDataObj)(mergeData);
            callback(_mergeData);
        },
        $getUnitInputData({ unitId }, callback) {
            const state = graph.getUnitInputData(unitId);
            callback(state);
        },
    };
    return obj;
};
exports.AsyncGGet = AsyncGGet;
const AsyncGCall = (graph) => {
    function call(method, fork, bubble, ...args) {
        return _call(graph, method, fork, bubble, ...args);
    }
    const obj = {
        $setUnitId({ unitId, newUnitId, name, specId, fork = true, bubble = true, }) {
            call('setUnitId', fork, bubble, unitId, newUnitId, name, specId);
        },
        $setUnitPinData({ unitId, pinId, type, data, fork = true, bubble = true, }) {
            const { specs, classes } = graph.__system;
            data = (0, evaluate_1.evaluate)(data, specs, classes);
            call('setUnitPinData', fork, bubble, unitId, type, pinId, data, true);
        },
        $removeUnitPinData({ unitId, type, pinId, fork = true, bubble = true, }) {
            call('removeUnitPinData', fork, bubble, unitId, type, pinId);
        },
        $addUnit({ unitId, bundle, parentId, fork = true, bubble = true, }) {
            call('addUnitSpec', fork, bubble, unitId, bundle, parentId);
        },
        $cloneUnit({ unitId, newUnitId, fork = true, bubble = true, }) {
            call('cloneUnit', fork, bubble, unitId, newUnitId);
        },
        $removeUnit({ unitId, take, fork = true, bubble = true, }) {
            call('removeUnit', fork, bubble, unitId, undefined, take, undefined);
        },
        $exposePinSet({ type, pinId, pinSpec, data, fork = true, bubble = true, }) {
            const data_ = data && (0, evaluate_1.evaluate)(data, graph.__system.specs, graph.__system.classes);
            call('exposePinSet', fork, bubble, type, pinId, pinSpec, data_, undefined, undefined);
        },
        $coverPinSet({ type, pinId, fork = true, bubble = true, }) {
            call('coverPinSet', fork, bubble, type, pinId, true);
        },
        $exposePin({ type, pinId, subPinId, subPinSpec, fork = true, bubble = true, }) {
            call('exposePin', fork, bubble, type, pinId, subPinId, subPinSpec);
        },
        $coverPin({ type, pinId, subPinId, fork = true, bubble = true, }) {
            call('coverPin', fork, bubble, type, pinId, subPinId);
        },
        $plugPin({ type, pinId, subPinId, subPinSpec, fork = true, bubble = true, }) {
            call('plugPin', fork, bubble, type, pinId, subPinId, subPinSpec);
        },
        $unplugPin({ type, pinId, subPinId, take, fork = true, bubble = true, }) {
            call('unplugPin', fork, bubble, type, pinId, subPinId, true, take);
        },
        $exposeUnitPinSet({ unitId, type, pinId, pinSpec, fork = true, bubble = true, }) {
            const unit = graph.getUnit(unitId);
            _call(unit, 'exposePinSet', fork, bubble, type, pinId, pinSpec, undefined, undefined, undefined);
        },
        $coverUnitPinSet({ unitId, type, pinId, fork = true, bubble = true, }) {
            const unit = graph.getUnit(unitId);
            _call(unit, 'coverPinSet', fork, bubble, type, pinId);
        },
        $setPinSetId({ type, pinId, nextPinId, fork = true, bubble = true, }) {
            call('setPinSetId', fork, bubble, type, pinId, nextPinId);
        },
        $setPinSetFunctional({ type, pinId, functional, fork = true, bubble = true, }) {
            call('setPinSetFunctional', fork, bubble, type, pinId, functional);
        },
        $setUnitPinConstant({ unitId, type, pinId, constant, fork = true, bubble = true, }) {
            call('setUnitPinConstant', fork, bubble, unitId, type, pinId, constant, true);
        },
        $setUnitPinIgnored({ unitId, type, pinId, ignored, fork = true, bubble = true, }) {
            call('setUnitPinIgnored', fork, bubble, unitId, type, pinId, ignored);
        },
        $setUnitPinSetId({ unitId, type, pinId, nextPinId, fork = true, bubble = true, }) {
            call('setUnitPinSetId', fork, bubble, unitId, type, pinId, nextPinId);
        },
        $addMerge({ mergeId, mergeSpec, fork = true, bubble = true, }) {
            call('addMerge', fork, bubble, mergeSpec, mergeId, undefined, undefined, undefined);
        },
        $removeMerge({ mergeId, take, fork = true, bubble = true, }) {
            call('removeMerge', fork, bubble, mergeId, undefined, take);
        },
        $addPinToMerge({ mergeId, unitId, type, pinId, fork = true, bubble = true, }) {
            call('addPinToMerge', fork, bubble, mergeId, unitId, type, pinId);
        },
        $removePinFromMerge({ mergeId, unitId, type, pinId, take, fork = true, bubble = true, }) {
            call('removePinFromMerge', fork, bubble, mergeId, unitId, type, pinId, true, take);
        },
        $removeUnitGhost({ unitId, nextUnitId, nextUnitSpec, fork = true, bubble = true, }, callback) {
            const ghost = call('removeUnitGhost', fork, bubble, unitId, nextUnitId, nextUnitSpec);
            const ghost_ = (0, clone_1.clone)(ghost);
            (0, stringifySpec_1.stringifyUnitBundleSpecData)(ghost_.bundle);
            callback(ghost_);
        },
        $addUnitGhost({ unitId, nextUnitId, nextUnitBundle, nextUnitPinMap, fork = true, bubble = true, }) {
            call('addUnitGhost', fork, bubble, unitId, nextUnitId, (0, clone_1.clone)(nextUnitBundle), nextUnitPinMap);
        },
        $setMetadata({ path, data, fork = true, bubble = true, }) {
            call('setMetadata', fork, bubble, path, data);
        },
        $reorderSubComponent({ parentId, childId, to, fork = true, bubble = true, }) {
            call('reorderSubComponent', fork, bubble, parentId, childId, to);
        },
        $moveSubComponentRoot({ parentId, children, slotMap, fork = true, bubble = true, }) {
            call('moveSubComponentRoot', fork, bubble, parentId, children, slotMap);
        },
        $moveSubgraphInto({ graphId, nextSpecId, nodeIds, nextIdMap, nextPinIdMap, nextMergePinId, nextPlugSpec, nextSubComponentParentMap, nextSubComponentChildrenMap, fork = true, bubble = true, }) {
            const graphBundle = graph.getGraphUnitUnitBundleSpec(graphId);
            const graphSpec = graph.getGraphUnitGraphSpec(graphId);
            call('moveSubgraphInto', fork, bubble, graphId, graphBundle, graphSpec, nextSpecId, nodeIds, nextIdMap, nextPinIdMap, nextMergePinId, nextPlugSpec, nextSubComponentParentMap, nextSubComponentChildrenMap);
        },
        $moveSubgraphOutOf({ graphId, nextSpecId, nodeIds, nextIdMap, nextPinIdMap, nextMergePinId, nextPlugSpec, nextSubComponentParentMap, nextSubComponentChildrenMap, fork = true, bubble = true, }) {
            const graphBundle = graph.getGraphUnitUnitBundleSpec(graphId);
            const graphSpec = graph.getGraphUnitGraphSpec(graphId);
            call('moveSubgraphOutOf', fork, bubble, graphId, graphBundle, graphSpec, nextSpecId, nodeIds, nextIdMap, nextPinIdMap, nextMergePinId, nextPlugSpec, nextSubComponentParentMap, nextSubComponentChildrenMap);
        },
        $bulkEdit({ actions, fork = true, bubble = true }) {
            call('bulkEdit', fork, bubble, actions);
        },
        $setMergeData({ mergeId, data, fork = true, bubble = true, }) {
            const system = graph.refSystem();
            const { specs, classes } = system;
            const _data = (0, evaluate_1.evaluate)(data, specs, classes);
            graph.setMergeData(mergeId, _data);
        },
        $removeMergeData({ mergeId, fork = true, bubble = true, }) {
            graph.removeMergeData(mergeId);
        },
        $takeUnitErr({ unitId, fork = true, bubble = true, }) {
            graph.takeUnitErr(unitId);
        },
        $setPinSetDefaultIgnored({ type, pinId, defaultIgnored, fork, bubble, }) {
            call('setPinSetDefaultIgnored', fork, bubble, type, pinId, defaultIgnored);
        },
    };
    return obj;
};
exports.AsyncGCall = AsyncGCall;
const AsyncGWatch = (graph) => {
    return {
        $watchGraph({ events }, callback) {
            return (0, watchGraph_1.watchGraph)(graph, callback, events);
        },
        $watchUnit({ unitId, events }, callback) {
            const unit = graph.getUnit(unitId);
            return (0, watchUnit_1.watchUnit)(unit, callback, events);
        },
        $watchGraphUnit({ unitId, events }, callback) {
            const graph = this.refUnit(unitId);
            return (0, watchGraph_1.watchGraph)(graph, callback, events);
        },
        $watchUnitPath({ path, events }, callback) {
            const unit = graph.getUnitByPath(path);
            return (0, watchUnit_1.watchUnit)(unit, callback, events);
        },
        $watchGraphUnitPath({ path, events }, callback) {
            const unit = graph.getUnitByPath(path);
            return (0, watchGraph_1.watchGraph)(unit, callback, events);
        },
    };
};
exports.AsyncGWatch = AsyncGWatch;
const AsyncGRef = (graph) => {
    return {
        $refUnit({ unitId, _ }) {
            const unit = graph.getUnit(unitId);
            const $unit = (0, Async_1.Async)(unit, _, graph.__system.async);
            return $unit;
        },
        $refSubComponent({ unitId, _, }) {
            const unit = graph.getUnit(unitId);
            const $unit = (0, Async_1.Async)(unit, _, graph.__system.async);
            return $unit;
        },
    };
};
exports.AsyncGRef = AsyncGRef;
const AsyncG = (graph) => {
    return {
        ...(0, exports.AsyncGGet)(graph),
        ...(0, exports.AsyncGWatch)(graph),
        ...(0, exports.AsyncGCall)(graph),
        ...(0, exports.AsyncGRef)(graph),
    };
};
exports.AsyncG = AsyncG;
//# sourceMappingURL=AsyncG.js.map