"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Container = void 0;
const core_1 = require("@inversifyjs/core");
const BindingManager_1 = require("./BindingManager");
const ContainerModuleManager_1 = require("./ContainerModuleManager");
const DeactivationParamsManager_1 = require("./DeactivationParamsManager");
const PlanParamsOperationsManager_1 = require("./PlanParamsOperationsManager");
const PlanResultCacheManager_1 = require("./PlanResultCacheManager");
const PluginManager_1 = require("./PluginManager");
const ServiceReferenceManager_1 = require("./ServiceReferenceManager");
const ServiceResolutionManager_1 = require("./ServiceResolutionManager");
const SnapshotManager_1 = require("./SnapshotManager");
const DEFAULT_DEFAULT_SCOPE = core_1.bindingScopeValues.Transient;
class Container {
    #bindingManager;
    #containerModuleManager;
    #pluginManager;
    #serviceReferenceManager;
    #serviceResolutionManager;
    #snapshotManager;
    constructor(options) {
        const autobind = options?.autobind ?? false;
        const defaultScope = options?.defaultScope ?? DEFAULT_DEFAULT_SCOPE;
        this.#serviceReferenceManager = this.#buildServiceReferenceManager(options, autobind, defaultScope);
        const planParamsOperationsManager = new PlanParamsOperationsManager_1.PlanParamsOperationsManager(this.#serviceReferenceManager);
        const planResultCacheManager = new PlanResultCacheManager_1.PlanResultCacheManager(planParamsOperationsManager, this.#serviceReferenceManager);
        const deactivationParamsManager = new DeactivationParamsManager_1.DeactivationParamsManager(this.#serviceReferenceManager);
        this.#bindingManager = new BindingManager_1.BindingManager(deactivationParamsManager.deactivationParams, defaultScope, planResultCacheManager, this.#serviceReferenceManager);
        this.#containerModuleManager = new ContainerModuleManager_1.ContainerModuleManager(this.#bindingManager, deactivationParamsManager.deactivationParams, defaultScope, planResultCacheManager, this.#serviceReferenceManager);
        this.#serviceResolutionManager = new ServiceResolutionManager_1.ServiceResolutionManager(planParamsOperationsManager, this.#serviceReferenceManager, autobind, defaultScope);
        this.#pluginManager = new PluginManager_1.PluginManager(this, this.#serviceReferenceManager, this.#serviceResolutionManager);
        this.#snapshotManager = new SnapshotManager_1.SnapshotManager(this.#serviceReferenceManager);
    }
    bind(serviceIdentifier) {
        return this.#bindingManager.bind(serviceIdentifier);
    }
    get(serviceIdentifier, options) {
        return this.#serviceResolutionManager.get(serviceIdentifier, options);
    }
    getAll(serviceIdentifier, options) {
        return this.#serviceResolutionManager.getAll(serviceIdentifier, options);
    }
    async getAllAsync(serviceIdentifier, options) {
        return this.#serviceResolutionManager.getAllAsync(serviceIdentifier, options);
    }
    async getAsync(serviceIdentifier, options) {
        return this.#serviceResolutionManager.getAsync(serviceIdentifier, options);
    }
    isBound(serviceIdentifier, options) {
        return this.#bindingManager.isBound(serviceIdentifier, options);
    }
    isCurrentBound(serviceIdentifier, options) {
        return this.#bindingManager.isCurrentBound(serviceIdentifier, options);
    }
    async load(...modules) {
        return this.#containerModuleManager.load(...modules);
    }
    loadSync(...modules) {
        this.#containerModuleManager.loadSync(...modules);
    }
    onActivation(serviceIdentifier, activation) {
        this.#serviceReferenceManager.activationService.add(activation, {
            serviceId: serviceIdentifier,
        });
    }
    onDeactivation(serviceIdentifier, deactivation) {
        this.#serviceReferenceManager.deactivationService.add(deactivation, {
            serviceId: serviceIdentifier,
        });
    }
    register(pluginConstructor) {
        this.#pluginManager.register(this, pluginConstructor);
    }
    restore() {
        this.#snapshotManager.restore();
    }
    async rebind(serviceIdentifier) {
        return this.#bindingManager.rebind(serviceIdentifier);
    }
    rebindSync(serviceIdentifier) {
        return this.#bindingManager.rebindSync(serviceIdentifier);
    }
    snapshot() {
        this.#snapshotManager.snapshot();
    }
    async unbind(identifier) {
        await this.#bindingManager.unbind(identifier);
    }
    async unbindAll() {
        await this.#bindingManager.unbindAll();
    }
    unbindAllSync() {
        this.#bindingManager.unbindAllSync();
    }
    unbindSync(identifier) {
        this.#bindingManager.unbindSync(identifier);
    }
    async unload(...modules) {
        return this.#containerModuleManager.unload(...modules);
    }
    unloadSync(...modules) {
        this.#containerModuleManager.unloadSync(...modules);
    }
    #buildAutobindOptions(autobind, defaultScope) {
        if (autobind) {
            return { scope: defaultScope };
        }
        return undefined;
    }
    #buildServiceReferenceManager(options, autobind, defaultScope) {
        const autobindOptions = this.#buildAutobindOptions(autobind, defaultScope);
        if (options?.parent === undefined) {
            return new ServiceReferenceManager_1.ServiceReferenceManager(core_1.ActivationsService.build(() => undefined), core_1.BindingService.build(() => undefined, autobindOptions), core_1.DeactivationsService.build(() => undefined), new core_1.PlanResultCacheService());
        }
        const planResultCacheService = new core_1.PlanResultCacheService();
        const parent = options.parent;
        parent.#serviceReferenceManager.planResultCacheService.subscribe(planResultCacheService);
        return new ServiceReferenceManager_1.ServiceReferenceManager(core_1.ActivationsService.build(() => parent.#serviceReferenceManager.activationService), core_1.BindingService.build(() => parent.#serviceReferenceManager.bindingService, autobindOptions), core_1.DeactivationsService.build(() => parent.#serviceReferenceManager.deactivationService), planResultCacheService);
    }
}
exports.Container = Container;
//# sourceMappingURL=Container.js.map