/**
 * ServiceContainer - Dependency Injection Container
 * Manages service registration and resolution with proven dependency injection patterns
 */
import { ErrorFactory } from '../exceptions/ZintrustError.js';
/**
 * ServiceContainer - Dependency Injection Container
 * Refactored to Functional Object pattern
 */
export const ServiceContainer = Object.freeze({
    /**
     * Create a new service container instance
     */
    create() {
        const bindings = new Map();
        const singletons = new Map();
        return {
            /**
             * Register a service binding
             */
            bind(key, factory) {
                bindings.set(key, {
                    factory: factory,
                    singleton: false,
                });
            },
            /**
             * Register a singleton service (instantiated once)
             */
            singleton(key, factoryOrInstance) {
                const isFactory = typeof factoryOrInstance === 'function';
                bindings.set(key, {
                    factory: isFactory ? factoryOrInstance : () => factoryOrInstance,
                    singleton: true,
                });
            },
            /**
             * Resolve a service from the container
             */
            resolve(key) {
                const binding = bindings.get(key);
                if (binding === undefined) {
                    throw ErrorFactory.createNotFoundError(`Service "${key}" is not registered in the container`, { key });
                }
                if (binding.singleton === true) {
                    if (singletons.has(key) === false) {
                        singletons.set(key, binding.factory());
                    }
                    return singletons.get(key);
                }
                return binding.factory();
            },
            /**
             * Check if a service is registered
             */
            has(key) {
                return bindings.has(key);
            },
            /**
             * Get a service (alias for resolve)
             */
            get(key) {
                return this.resolve(key);
            },
            /**
             * Clear all bindings and singletons
             */
            flush() {
                bindings.clear();
                singletons.clear();
            },
        };
    },
});
export default ServiceContainer;
