import { AwilixContainer } from "awilix";
import { ErrorChain } from "../lib/error";
import { Environment } from "./Environment";
import { ELogLevel, ILogMessage, ILogMetadata } from "./Log";
import { EMetricType, IMetricTags } from "./Metric";
import { BehaviorSubject, Observable, Subject } from "./RxJS";
import { IModule, IModuleConstructor, IModuleState } from "./Types";
/** Command line arguments interface matching 'yargs' package. */
export interface IContainerArguments {
    /** Non-option arguments */
    _: string[];
    /** The script name or node command */
    $0: string;
    /** All remaining options */
    [argName: string]: any;
}
/** Container error class. */
export declare class ContainerError extends ErrorChain {
    constructor(name: string, cause?: Error);
}
/** Container log message interface. */
export interface IContainerLogMessage {
    level: ELogLevel;
    message: ILogMessage;
    metadata: ILogMetadata;
    args: any[];
}
/** Log message class for stream of module logs. */
export declare class ContainerLogMessage implements IContainerLogMessage {
    level: ELogLevel;
    message: ILogMessage;
    metadata: ILogMetadata;
    args: any[];
    constructor(level: ELogLevel, message: ILogMessage, metadata: ILogMetadata, args: any[]);
}
/** Container metric message interface. */
export interface IContainerMetricMessage {
    type: EMetricType;
    name: string;
    value: any;
    tags: IMetricTags;
}
/** Metric message class for stream of module metrics. */
export declare class ContainerMetricMessage implements IContainerMetricMessage {
    type: EMetricType;
    name: string;
    value: any;
    tags: IMetricTags;
    constructor(type: EMetricType, name: string, value: any, tags: IMetricTags);
}
/** Wrapper around awilix library. */
export declare class Container {
    /** Container name, used to namespace modules. */
    readonly name: string;
    /** Container environment. */
    readonly environment: Environment;
    /** Optional command line arguments. */
    readonly argv: IContainerArguments;
    /** Container reference name used internally by modules. */
    static readonly REFERENCE: string;
    /** Error names. */
    static readonly ERROR: {
        UP: string;
        DOWN: string;
        MODULE_REGISTERED: string;
    };
    /** Log names. */
    static readonly LOG: {
        UP: string;
        DOWN: string;
    };
    /** Root container. */
    readonly container: AwilixContainer;
    /** Observable module state. */
    readonly modules$: BehaviorSubject<IModuleState>;
    /** Array of registered module names. */
    readonly moduleNames: string[];
    /** Array of registered modules. */
    readonly modules: IModule[];
    /** Container module logs. */
    readonly logs$: Subject<ContainerLogMessage>;
    /** Container module metrics. */
    readonly metrics$: Subject<ContainerMetricMessage>;
    /** Creates a new container in proxy resolution mode. */
    constructor(
        /** Container name, used to namespace modules. */
        name: string, 
        /** Container environment. */
        environment?: Environment, 
        /** Optional command line arguments. */
        argv?: IContainerArguments);
    /** Create scope from container. */
    createScope(): AwilixContainer;
    /**
     * Register a named module in container.
     * Throws an error if module of name is already registered.
     */
    registerModule(instance: IModuleConstructor): Container;
    /** Register named modules in container. */
    registerModules(modules: IModuleConstructor[]): Container;
    /** Register a value of type in container. */
    registerValue<T>(name: string, value: T): Container;
    /** Resolve value or module of type from container by name. */
    resolve<T>(name: string): T;
    /** Send log message of level for module. */
    sendLog(level: ELogLevel, message: ILogMessage, metadata: ILogMetadata, args: any[]): void;
    /** Send metric message of type for module. */
    sendMetric(type: EMetricType, name: string, value: any, tags: IMetricTags): void;
    /** Observable stream of module logs filtered by level. */
    filterLogs(level: ELogLevel): Observable<ContainerLogMessage>;
    /** Observable stream of module metrics filtered by type. */
    filterMetrics(type: EMetricType): Observable<ContainerMetricMessage>;
    /** Signal modules to enter operational state. */
    up(timeout?: number): Observable<void>;
    /** Signal modules to leave operational state. */
    down(timeout?: number): Observable<void>;
    /** Wait for modules to enter operational state before calling next. */
    protected waitUp(...modules: string[]): Observable<void>;
    /** Wait for modules to leave operational state before calling next. */
    protected waitDown(...modules: string[]): Observable<void>;
    protected moduleFactory<T extends IModuleConstructor>(instance: T, opts: any): IModule;
    protected moduleDependencies(mod: IModule): string[];
    protected moduleDependants(mod: IModule): string[];
    protected moduleRegistered(name: string): boolean;
    protected moduleState(name: string, state: boolean): Observable<void>;
    protected containerState(observables$: Array<Observable<void>>, state: boolean, timeout?: number): Observable<void>;
}
