"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeServiceNodeBindingIfContextFree = removeServiceNodeBindingIfContextFree;
const BindingConstraintsImplementation_1 = require("../../binding/models/BindingConstraintsImplementation");
const InversifyCoreError_1 = require("../../error/models/InversifyCoreError");
const InversifyCoreErrorKind_1 = require("../../error/models/InversifyCoreErrorKind");
const LazyPlanServiceNode_1 = require("../models/LazyPlanServiceNode");
/**
 * Detach a binding to the root service node if it is context-free.
 * @param serviceNode The service node to attach the binding to.
 * @param binding The binding to attach.
 * @param bindingConstraintsList The list of binding constraints.
 * @param optionalBindings Whether the bindings are optional.
 * @returns True if the binding requires ancestor metadata, false otherwise.
 */
function removeServiceNodeBindingIfContextFree(serviceNode, binding, bindingConstraintsList, optionalBindings) {
    if (LazyPlanServiceNode_1.LazyPlanServiceNode.is(serviceNode) && !serviceNode.isExpanded()) {
        return {
            bindingNodeRemoved: undefined,
            isContextFreeBinding: true,
        };
    }
    const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(bindingConstraintsList.last);
    if (!binding.isSatisfiedBy(bindingConstraints) ||
        bindingConstraintsList.last.elem.getAncestorsCalled) {
        return {
            bindingNodeRemoved: undefined,
            isContextFreeBinding: !bindingConstraintsList.last.elem.getAncestorsCalled,
        };
    }
    let bindingNodeRemoved;
    if (Array.isArray(serviceNode.bindings)) {
        serviceNode.bindings = serviceNode.bindings.filter((bindingNode) => {
            if (bindingNode.binding === binding) {
                bindingNodeRemoved = bindingNode;
                return false;
            }
            return true;
        });
    }
    else {
        if (serviceNode.bindings?.binding === binding) {
            bindingNodeRemoved = serviceNode.bindings;
            if (optionalBindings) {
                serviceNode.bindings = undefined;
            }
            else {
                if (!LazyPlanServiceNode_1.LazyPlanServiceNode.is(serviceNode)) {
                    throw new InversifyCoreError_1.InversifyCoreError(InversifyCoreErrorKind_1.InversifyCoreErrorKind.planning, 'Unexpected non-lazy plan service node. This is likely a bug in the planning logic. Please, report this issue');
                }
                serviceNode.invalidate();
            }
        }
    }
    return {
        bindingNodeRemoved: bindingNodeRemoved,
        isContextFreeBinding: true,
    };
}
//# sourceMappingURL=removeServiceNodeBindingIfContextFree.js.map