/// <reference types="debug" />
import * as Debug from "debug";
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/of";
import "rxjs/add/observable/throw";
import "rxjs/add/observable/forkJoin";
import "rxjs/add/operator/catch";
import "rxjs/add/operator/filter";
import "rxjs/add/operator/switchMap";
import "rxjs/add/operator/take";
import "rxjs/add/operator/timeout";
import { Environment } from "./Environment";
import { ELogLevel, ILogMessage, ILogMetadata, Log } from "./Log";
import { EMetricType, IMetricTags, Metric } from "./Metric";
/** Container options injected by awilix library. */
export interface IContainerModuleOpts {
    [key: string]: any;
}
/** Container module constructor interface. */
export interface IContainerModuleConstructor {
    name: string;
    new (name: string, opts: IContainerModuleOpts): ContainerModule;
}
/** Container module dependencies. */
export interface IContainerModuleDepends {
    [key: string]: string;
}
/** Module state interface. */
export interface IContainerModuleState {
    [key: string]: boolean;
}
/** Container error class. */
export declare class ContainerError extends Error {
    constructor(message: string);
}
/** 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);
}
/** Container reference name used internally by modules. */
export declare const CONTAINER_NAME = "_container";
/** Wrapper around awilix library. */
export declare class Container {
    private _name;
    private _environment;
    private _container;
    private _modules;
    private _logs;
    private _metrics;
    /** Container name, used to namespace modules. */
    readonly name: string;
    /** Container environment reference available to modules. */
    readonly environment: Environment;
    /** Array of registered module names. */
    readonly modules: string[];
    /** Container logs. */
    readonly logs: Observable<ContainerLogMessage>;
    /** Container metrics. */
    readonly metrics: Observable<ContainerMetricMessage>;
    /** Creates a new container in proxy resolution mode. */
    constructor(_name: string, environment?: Environment);
    /** Register a module in container, has singleton lifetime by default. */
    registerModule<T extends IContainerModuleConstructor>(instance: T, lifetime?: string): Container;
    /** Register a value in container. */
    registerValue<T>(name: string, value: T): Container;
    /** Resolve module in 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 logs filtered by level. */
    filterLogs(level: ELogLevel): Observable<ContainerLogMessage>;
    /** Signal modules to enter operational state. */
    start(timeout?: number): Observable<void>;
    /** Signal modules to leave operational state. */
    stop(timeout?: number): Observable<void>;
    /** Wait for modules to start before calling next. */
    waitStarted(...modules: string[]): Observable<void>;
    /** Wait for modules to stop before calling next. */
    waitStopped(...modules: string[]): Observable<void>;
    /** Factory functions for modules. */
    protected makeModule<T extends IContainerModuleConstructor>(name: string, instance: T, opts: IContainerModuleOpts): ContainerModule;
    /** Set modules state by calling start/stop methods. */
    protected setModulesState(state: boolean, timeout?: number): Observable<void>;
    /** Update and report module state via internal subject. */
    protected reportModuleState(name: string, state: boolean): Observable<void>;
}
/** Container module log class. */
export declare class ContainerModuleLog extends Log {
    private _container;
    private _name;
    constructor(_container: Container, _name: string);
    /**
     * Sends log message to container bus for consumption by modules.
     * Adds module name to metadata object by default.
     */
    protected log(level: ELogLevel, message: ILogMessage, metadata: ILogMetadata, ...args: any[]): void;
}
/** Container module metric class. */
export declare class ContainerModuleMetric extends Metric {
    private _container;
    private _name;
    constructor(_container: Container, _name: string);
    /**
     * Sends metric message to container bus for consumption by modules.
     * Adds module name to tags object by default.
     */
    protected metric(type: EMetricType, name: string, value: any, tags: IMetricTags): void;
}
/** Base class for container class modules with dependency injection. */
export declare class ContainerModule {
    private _container;
    private _name;
    private _log;
    private _metric;
    private _debug;
    private _identifier;
    /** Module container reference. */
    readonly container: Container;
    /** Module container environment reference. */
    readonly environment: Environment;
    /** Module name. */
    readonly name: string;
    /** Module container and module names. */
    readonly namespace: string;
    /** Module log interface. */
    readonly log: ContainerModuleLog;
    /** Module metric interface. */
    readonly metric: ContainerModuleMetric;
    /** Module debug interface. */
    readonly debug: Debug.IDebugger;
    /** Incrementing counter for unique identifiers. */
    protected readonly identifier: number;
    constructor(name: string, opts: IContainerModuleOpts, depends?: IContainerModuleDepends);
    /** Module operational state. */
    start(): Observable<void>;
    /** Module non-operational state. */
    stop(): Observable<void>;
}
