/*
 * Copyright 2025 Saulo V. Alvarenga. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { AddDependencyCommandHandler } from "./commands/add-dependency";
import { ResolveDependencyCommandHandler } from "./commands/resolve-dependency";
import { CheckForCyclicDependenciesCommandHandler } from "./commands/check-for-cyclic-dependencies";
import { ResolveSingletonsCommandHandler } from "./commands/resolve-singletons";
import { DependencyResolver } from "./dependency";
import { DependencyStore } from "./dependency";
import { TokenStore, TokenTypeResolver, TokenNameResolver } from "./token";
import { TClassConstructor } from "./types";
import { ExceptionHandler } from "./exceptions";
/**
 * Class representing a Dependency Container for managing dependencies.
 */
export declare class DependencyContainer {
    protected dependencyTokenStore: TokenStore;
    protected dependencyStore: DependencyStore;
    protected dependencyResolver: DependencyResolver;
    protected dependencyTokenType: TokenTypeResolver;
    protected dependencyTokenName: TokenNameResolver;
    protected exceptionHandler: ExceptionHandler;
    protected addDependencyCommandHandler: AddDependencyCommandHandler;
    protected checkForCyclicDependenciesCommandHandler: CheckForCyclicDependenciesCommandHandler;
    protected resolveDependencyCommandHandler: ResolveDependencyCommandHandler;
    protected resolveSingletonsCommandHandler: ResolveSingletonsCommandHandler;
    protected isContainerBuilt: boolean;
    protected isBuildSingletonsRequired: boolean;
    protected dependencyContainerToken: unknown;
    /**
     * Constructor to initialize the DependencyContainer with optional configurations.
     * @param {Object} [config] - Configuration options for the container.
     */
    constructor(config?: {
        disableDefaultResolveLifecycleStrategies?: boolean;
        disableDefaultTokenTypeCheckers?: boolean;
        disableDefaultTokenNameStrategies?: boolean;
        buildSingletonsRequired?: boolean;
        customDependencyContainerToken?: unknown;
    });
    protected loadConfigs(config?: {
        disableDefaultResolveLifecycleStrategies?: boolean;
        disableDefaultTokenTypeCheckers?: boolean;
        disableDefaultTokenNameStrategies?: boolean;
        buildSingletonsRequired?: boolean;
        customDependencyContainerToken?: unknown;
    }): void;
    protected exceptionHandlerWrapper<T>(callback: () => any): T;
    /**
     * Builds all singleton dependencies.
     * @returns {DependencyContainer} The current instance of the container.
     */
    buildSingletons(): DependencyContainer;
    checkForCyclicDependencies(): this;
    protected addDependency<TToken, TInstance = TToken>(config: {
        lifecycle: string;
        dependencyToken?: TToken;
        qualifierToken?: unknown;
        classConstructor?: TClassConstructor;
        builder?: () => TInstance;
        instance?: TInstance;
    }): void;
    protected retrieveDependency(config: {
        dependencyToken?: unknown;
        qualifierToken?: unknown;
    }): any;
    /**
     * Adds a singleton dependency using a builder function.
     * @param {Object} config - The configuration object.
     * @param {Function} config.builder - The builder function to create the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addSingletonBuilder<TToken, TInstance = TToken>(config: {
        builder: () => TToken;
    }): void;
    addSingletonBuilder<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        builder: () => TInstance;
    }): void;
    /**
     * Adds a mapped singleton dependency using a builder function.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {Function} config.builder - The builder function to create the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addMappedSingletonBuilder<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
        builder: () => TToken;
    }): void;
    addMappedSingletonBuilder<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        qualifierToken: unknown;
        builder: () => TInstance;
    }): void;
    /**
     * Adds a singleton dependency using an instance.
     * @param {Object} config - The configuration object.
     * @param {TInstance} config.instance - The instance of the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addSingletonInstance<TToken, TInstance = TToken>(config: {
        instance: TToken;
    }): void;
    addSingletonInstance<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        instance: TToken;
    }): void;
    /**
     * Adds a mapped singleton dependency using an instance.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {TInstance} config.instance - The instance of the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addMappedSingletonInstance<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
        instance: TToken;
    }): void;
    addMappedSingletonInstance<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        qualifierToken: unknown;
        instance: TToken;
    }): void;
    /**
     * Adds a singleton dependency using a class constructor.
     * @param {Object} [config] - The configuration object.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     * @param {TClassConstructor} [config.classConstructor] - Optional class constructor for the dependency.
     */
    addSingleton<TToken, TInstance = TToken>(): void;
    addSingleton<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken extends TClassConstructor ? TToken : unknown;
        classConstructor?: TClassConstructor;
    }): void;
    /**
     * Adds a mapped singleton dependency using a class constructor.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     * @param {TClassConstructor} [config.classConstructor] - Optional class constructor for the dependency.
     */
    addMappedSingleton<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
    }): void;
    addMappedSingleton<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
        dependencyToken?: TToken extends TClassConstructor ? TToken : unknown;
        classConstructor?: TClassConstructor;
    }): void;
    /**
     * Adds a transient dependency using a builder function.
     * @param {Object} config - The configuration object.
     * @param {Function} config.builder - The builder function to create the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addTransientBuilder<TToken, TInstance = TToken>(config: {
        builder: () => TToken;
    }): void;
    addTransientBuilder<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        builder: () => TInstance;
    }): void;
    /**
     * Adds a mapped transient dependency using a builder function.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {Function} config.builder - The builder function to create the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addMappedTransientBuilder<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
        builder: () => TInstance;
    }): void;
    addMappedTransientBuilder<TToken, TInstance = TToken>(config: {
        dependencyToken?: TToken;
        qualifierToken: unknown;
        builder: () => TInstance;
    }): void;
    /**
     * Adds a transient dependency using a class constructor.
     * @param {Object} [config] - The configuration object.
     * @param {TClassConstructor} [config.classConstructor] - The class constructor for the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     */
    addTransient<TToken, TInstance = TToken>(): void;
    addTransient<TToken, TInstance = TToken>(config?: {
        dependencyToken?: TToken extends TClassConstructor ? TToken : unknown;
        classConstructor?: TClassConstructor;
    }): void;
    /**
     * Adds a mapped transient dependency using a class constructor.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {TToken} [config.dependencyToken] - Optional token for the dependency.
     * @param {TClassConstructor} [config.classConstructor] - Optional class constructor for the dependency.
     */
    addMappedTransient<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
    }): void;
    addMappedTransient<TToken, TInstance = TToken>(config: {
        qualifierToken: unknown;
        dependencyToken?: TToken extends TClassConstructor ? TToken : unknown;
        classConstructor?: TClassConstructor;
    }): void;
    /**
     * Retrieves a dependency by its token.
     * @param {Object} [config] - The configuration object.
     * @param {TToken} [config.dependencyToken] - The token of the dependency to retrieve.
     * @returns {TToken} The resolved dependency instance.
     */
    getDependency<TToken>(): TToken extends new (...args: Array<any>) => infer TReturn ? TReturn : TToken extends symbol ? any : TToken;
    getDependency<TToken>(config?: {
        dependencyToken?: TToken;
    }): TToken extends new (...args: Array<any>) => infer TReturn ? TReturn : TToken extends symbol ? any : TToken;
    /**
     * Retrieves a mapped dependency by its token and qualifier.
     * @param {Object} config - The configuration object.
     * @param {unknown} config.qualifierToken - The token used to qualify the dependency.
     * @param {TToken} [config.dependencyToken] - The token of the dependency to retrieve.
     * @returns {TToken} The resolved dependency instance.
     */
    getMappedDependency<TToken>(config: {
        qualifierToken: unknown;
    }): TToken extends new (...args: Array<any>) => infer TReturn ? TReturn : TToken extends symbol ? any : TToken;
    getMappedDependency<TToken>(config: {
        dependencyToken?: TToken;
        qualifierToken: unknown;
    }): TToken extends new (...args: Array<any>) => infer TReturn ? TReturn : TToken extends symbol ? any : TToken;
    /**
     * Resets the dependency container to its initial state.
     * Remove all dependencies.
     */
    reset(): void;
}
