"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unitFromBundleSpec = unitFromBundleSpec;
const f_1 = require("../system/core/object/ForEachKeyValue/f");
const IOOf_1 = require("../types/IOOf");
const clone_1 = require("../util/clone");
const weakMerge_1 = require("../weakMerge");
const evaluateDataValue_1 = require("./evaluateDataValue");
const fromId_1 = require("./fromId");
const fromSpec_1 = require("./fromSpec");
const remapBundle_1 = require("./remapBundle");
const resolveDataValue_1 = require("./resolveDataValue");
function unitFromBundleSpec(system, bundle, specs, branch = {}) {
    var _a, _b;
    const specs_ = (0, weakMerge_1.weakMerge)(specs, (_a = bundle.specs) !== null && _a !== void 0 ? _a : {});
    (0, fromSpec_1.applyUnitDefaultIgnored)(bundle.unit, specs_);
    const { unit: { id, input }, } = bundle;
    const { classes } = system;
    const spec_map_id = system.injectSpecs((_b = bundle.specs) !== null && _b !== void 0 ? _b : {});
    (0, remapBundle_1.remapSpecs)(bundle, spec_map_id);
    const unit = (0, fromId_1.unitFromId)(system, id, specs_, classes, branch);
    (0, IOOf_1.io)((type) => {
        var _a;
        const pins = (_a = bundle.unit[type]) !== null && _a !== void 0 ? _a : {};
        (0, f_1.default)(pins, (pinSpec = {}, pinId) => {
            const { constant, ignored } = pinSpec;
            if (typeof constant === 'boolean') {
                unit.setPinConstant(type, pinId, constant);
            }
            if (typeof ignored === 'boolean') {
                unit.setPinIgnored(type, pinId, ignored);
            }
        });
    });
    const { unit: { memory }, } = bundle;
    if (memory) {
        const memory_ = (0, clone_1.clone)(memory);
        unit.restore(memory_);
    }
    (0, f_1.default)(input || {}, (unitPinSpec, pinId) => {
        const { data } = unitPinSpec !== null && unitPinSpec !== void 0 ? unitPinSpec : {};
        const dataRef = (0, evaluateDataValue_1.evaluateDataValue)(data, specs, classes);
        if (dataRef.data !== undefined) {
            const input = unit.getInput(pinId);
            const data_ = (0, resolveDataValue_1.resolveDataRef)(dataRef, specs, classes);
            input.push(data_);
        }
    });
    return unit;
}
//# sourceMappingURL=unitFromSpec.js.map