"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginManager = void 0;
const plugin_1 = require("@inversifyjs/plugin");
const InversifyContainerError_1 = require("../../error/models/InversifyContainerError");
const InversifyContainerErrorKind_1 = require("../../error/models/InversifyContainerErrorKind");
class PluginManager {
    #pluginApi;
    #pluginContext;
    #serviceResolutionManager;
    #serviceReferenceManager;
    constructor(container, serviceReferenceManager, serviceResolutionManager) {
        this.#serviceReferenceManager = serviceReferenceManager;
        this.#serviceResolutionManager = serviceResolutionManager;
        this.#pluginApi = this.#buildPluginApi(container);
        this.#pluginContext = this.#buildPluginContext();
    }
    register(container, pluginConstructor) {
        const pluginInstance = new pluginConstructor(container, this.#pluginContext);
        if (pluginInstance[plugin_1.isPlugin] !== true) {
            throw new InversifyContainerError_1.InversifyContainerError(InversifyContainerErrorKind_1.InversifyContainerErrorKind.invalidOperation, 'Invalid plugin. The plugin must extend the Plugin class');
        }
        pluginInstance.load(this.#pluginApi);
    }
    #buildPluginApi(container) {
        return {
            define: (name, 
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            method) => {
                if (Object.prototype.hasOwnProperty.call(container, name)) {
                    throw new InversifyContainerError_1.InversifyContainerError(InversifyContainerErrorKind_1.InversifyContainerErrorKind.invalidOperation, `Container already has a method named "${String(name)}"`);
                }
                container[name] =
                    method;
            },
            onPlan: this.#serviceResolutionManager.onPlan.bind(this.#serviceResolutionManager),
        };
    }
    #buildPluginContext() {
        const serviceReferenceManager = this.#serviceReferenceManager;
        return {
            get activationService() {
                return serviceReferenceManager.activationService;
            },
            get bindingService() {
                return serviceReferenceManager.bindingService;
            },
            get deactivationService() {
                return serviceReferenceManager.deactivationService;
            },
            get planResultCacheService() {
                return serviceReferenceManager.planResultCacheService;
            },
        };
    }
}
exports.PluginManager = PluginManager;
//# sourceMappingURL=PluginManager.js.map