"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.collectUnitIdSet = collectUnitIdSet;
exports.collectIdSetFromSpec = collectIdSetFromSpec;
exports.collectIdSetFromBundle = collectIdSetFromBundle;
const evaluateDataValue_1 = require("../spec/evaluateDataValue");
const _classes_1 = __importDefault(require("../system/_classes"));
const _specs_1 = __importDefault(require("../system/_specs"));
const object_1 = require("../util/object");
const weakMerge_1 = require("../weakMerge");
function collectUnitIdSet(unit, specs, set) {
    const { id, input = {} } = unit;
    for (const inputId in input) {
        const _input = input[inputId] ?? {};
        let { data } = _input;
        const buildBundleIdSet = (bundle) => {
            const unitSpec = _specs_1.default[bundle.unit.id] ??
                specs[bundle.unit.id] ??
                bundle.specs[bundle.unit.id];
            collectUnitIdSet(bundle.unit, specs, set);
            collectIdSetFromSpec(unitSpec, specs, set);
            for (const specId in bundle.specs) {
                const spec = bundle.specs[specId];
                collectIdSetFromSpec(spec, specs, set);
            }
        };
        if (data !== undefined) {
            const dataRef = (0, evaluateDataValue_1.evaluateDataValue)(data, _specs_1.default, _classes_1.default);
            for (const path of dataRef.ref ?? []) {
                const bundle = (0, object_1.deepGet)(dataRef.data, path);
                buildBundleIdSet(bundle);
            }
        }
    }
    const unit_spec = specs[id];
    if (unit_spec) {
        collectIdSetFromSpec(unit_spec, specs, set);
    }
    else {
        throw new Error(`spec id not found ${id}`);
    }
}
function collectIdSetFromSpec(spec, specs, set = new Set()) {
    const { units = {} } = spec;
    if (set.has(spec.id)) {
        return set;
    }
    set.add(spec.id);
    for (const unitId in units) {
        const unit = units[unitId];
        collectUnitIdSet(unit, specs, set);
    }
    ;
    spec.deps?.forEach((id) => {
        const dep_spec = _specs_1.default[id];
        collectIdSetFromSpec(dep_spec, specs, set);
    });
    if (spec.deps) {
        for (const specId of spec.deps) {
            const spec = _specs_1.default[specId];
            collectIdSetFromSpec(spec, specs, set);
        }
    }
    return set;
}
function collectIdSetFromBundle(bundle, set = new Set()) {
    const { spec = {}, specs = {} } = bundle;
    const specs_ = (0, weakMerge_1.weakMerge)(specs, _specs_1.default);
    collectIdSetFromSpec(spec, specs_, set);
    for (const specId in specs) {
        const spec = specs[specId];
        collectIdSetFromSpec(spec, specs_, set);
    }
    return set;
}
//# sourceMappingURL=collectIdSet.js.map