import * as i0 from '@angular/core';
import { InjectionToken, Provider } from '@angular/core';

/**
 * All supported levels supported by Lumberjack. Used to specify the severity of a log and to configure Lumberjack and the log drivers.
 *
 * @example
 * ```typescript
 * import { LumberjackLevel } from '@ngworker/lumberjack';
 * ```
 */
type LumberjackLevel = 'critical' | 'debug' | 'error' | 'info' | 'trace' | 'verbose' | 'warn';

/**
 * Level used to represent severity of a log.
 *
 * @example
 * ```typescript
 * import { LumberjackLogLevel } from '@ngworker/lumberjack';
 * ```
 */
type LumberjackLogLevel = Exclude<LumberjackLevel, 'verbose'>;

/**
 * A set of Levels used to configure a log driver. Lumberjack filters logs
 * passed to the log driver based on its configured log levels.
 *
 * @example
 * ```typescript
 * import { LumberjackConfigLevels } from '@ngworker/lumberjack';
 * ```
 */
type LumberjackConfigLevels = LumberjackLogLevel[] | [Extract<LumberjackLevel, 'verbose'>];

/**
 * Optional payload with custom properties for a log.
 *
 * This does not have to be the same for all logs.
 *
 * NOTE! Make sure that these properties are supported by your log drivers.
 */
interface LumberjackLogPayload {
    /**
     * A custom property for a log.
     *
     * NOTE! Make sure that this property is supported by your log drivers.
     */
    readonly [property: string]: unknown;
}

/**
 * A Lumberjack log. Optionally supports a payload.
 */
interface LumberjackLog<TPayload extends LumberjackLogPayload | void = void> {
    /**
     * Unix epoch ticks in milliseconds representing when the log was created.
     */
    readonly createdAt: number;
    /**
     * Level of severity.
     */
    readonly level: LumberjackLogLevel;
    /**
     * Log message, for example describing an event that happened.
     */
    readonly message: string;
    /**
     * Optional payload with custom properties.
     *
     * NOTE! Make sure that these properties are supported by your log drivers.
     */
    readonly payload?: TPayload;
    /**
     * Scope, for example domain, application, component, or service.
     */
    readonly scope?: string;
}

/**
 * The overridable Lumberjack format function is used to create the string
 * representation of a Lumberjack log.
 */
type LumberjackFormatFunction<TPayload extends LumberjackLogPayload | void = void> = (log: LumberjackLog<TPayload>) => string;

/**
 * Settings used internally by various Lumberjack services.
 */
interface LumberjackConfig<TPayload extends LumberjackLogPayload | void = void> {
    /**
     * The Lumberjack format function used to generate the text representation of
     * a log.
     */
    readonly format: LumberjackFormatFunction<TPayload>;
    /**
     * The default log level filter.
     */
    readonly levels: LumberjackConfigLevels;
}

/**
 * The Lumberjack configuration token is used internally by `provideLumberjack` function.
 * and various Lumberjack services.
 */
declare const lumberjackConfigToken: InjectionToken<LumberjackConfig>;

/**
 * Settings for a log driver.
 */
interface LumberjackLogDriverConfig {
    /**
     * Used to filter logs passed to the log driver based on the log's log level.
     *
     * `['verbose']` indicates that all log levels are allowed.
     */
    readonly levels: LumberjackConfigLevels;
    /**
     * Driver Identifier, necessary for driver filtering.
     */
    readonly identifier: string;
}

/**
 * The Lumberjack log driver configuration token is used internally by
 * `provideLumberjack` function, various internal Lumberjack services, and log drivers.
 */
declare const lumberjackLogDriverConfigToken: InjectionToken<LumberjackLogDriverConfig>;

/**
 * Shared Lumberjack settings used by `provideLumberjack` function.
 */
type LumberjackOptions = Partial<LumberjackConfig>;

/**
 * Returns the [dependency-injection providers](https://angular.io/guide/glossary#provider)
 * for the `LumberjackOptions`, `LumberjackConfig` and `LumberjackLogDriverConfig`.
 *
 * @usageNotes
 *
 * The function is useful when you want to bootstrap an application using
 * the `bootstrapApplication` function and want to make available the `Lumberjack` providers.
 *
 * ```typescript
 * bootstrapApplication(RootComponent, {
 *   providers: [
 *    provideLumberjack({...})
 *   ]
 * });
 * ```
 *
 * @publicApi
 */
declare function provideLumberjack(options?: LumberjackOptions): Provider[];

/**
 * The data structure passed to a log driver by Lumberjack. Optionally supports
 * a log payload.
 */
interface LumberjackLogDriverLog<TPayload extends LumberjackLogPayload | void = void> {
    /**
     * The text representation of the log.
     */
    readonly formattedLog: string;
    /**
     * The log. Optionally supports a log payload.
     */
    readonly log: LumberjackLog<TPayload>;
}

/**
 * The interface implemented by log drivers. Optionally supports a log payload.
 */
interface LumberjackLogDriver<TPayload extends LumberjackLogPayload | void = void> {
    /**
     * Log driver settings.
     */
    readonly config: LumberjackLogDriverConfig;
    /**
     * A critical log and its text representation is passed to this method.
     */
    logCritical(driverLog: LumberjackLogDriverLog<TPayload>): void;
    /**
     * A debug log and its text representation is passed to this method.
     */
    logDebug(driverLog: LumberjackLogDriverLog<TPayload>): void;
    /**
     * An error log and its text representation is passed to this method.
     */
    logError(driverLog: LumberjackLogDriverLog<TPayload>): void;
    /**
     * An info log and its text representation is passed to this method.
     */
    logInfo(driverLog: LumberjackLogDriverLog<TPayload>): void;
    /**
     * A trace log and its text representation is passed to this method.
     */
    logTrace(driverLog: LumberjackLogDriverLog<TPayload>): void;
    /**
     * A warning log and its text representation is passed to this method.
     */
    logWarning(driverLog: LumberjackLogDriverLog<TPayload>): void;
}

/**
 * A multi-provider token which log drivers use to register with Lumberjack.
 */
declare const lumberjackLogDriverToken: InjectionToken<LumberjackLogDriver>;

/**
 * Used by Lumberjack to timestamp logs at their creation time.
 *
 * Can be overridden for testing purposes.
 */
declare class LumberjackTimeService {
    /**
     * Return the current date-time as Unix epoch ticks in milliseconds.
     */
    getUnixEpochTicks(): number;
    static ɵfac: i0.ɵɵFactoryDeclaration<LumberjackTimeService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<LumberjackTimeService>;
}

/**
 * Service with programmatic API to pass logs to Lumberjack. Optionally
 * supports a log payload.
 *
 * Lumberjack passes the logs to the registered log drivers based on their
 * configurations.
 *
 * NOTE! Consider extending the `LumberjackLogger` or `ScopedLumberjackLogger`
 * base classes to set up predefined loggers unless you need a programmatic
 * API.
 */
declare class LumberjackService<TPayload extends LumberjackLogPayload | void = void> {
    #private;
    constructor();
    /**
     * Pass a log to Lumberjack which will be forwarded to the registered log
     * drivers based on their configurations.
     *
     * NOTE! It's recommended to use `LumberjackLogBuilder` to create the log.
     *
     * @param lumberjackLog The Lumberjack log. Optionally supports a log payload.
     */
    log(lumberjackLog: LumberjackLog<TPayload>): void;
    /**
     * Pass a critical log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logCritical(message: string, payload?: TPayload, scope?: string): void;
    /**
     * Pass an error log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logError(message: string, payload?: TPayload, scope?: string): void;
    /**
     * Pass a warning log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logWarning(message: string, payload?: TPayload, scope?: string): void;
    /**
     * Pass an info log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logInfo(message: string, payload?: TPayload, scope?: string): void;
    /**
     * Pass a debug log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logDebug(message: string, payload?: TPayload, scope?: string): void;
    /**
     * Pass a trace log to Lumberjack which will be forwarded to the registered
     * log drivers based on their configurations.
     *
     * @param message Log message, for example describing an event that happened.
     * @param payload An optional payload to add to the log.
     * @param scope An optional scope to add to the {@link LumberjackLog}.
     */
    logTrace(message: string, payload?: TPayload, scope?: string): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<LumberjackService<any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<LumberjackService<any>>;
}

declare class LumberjackLoggerBuilder<TPayload extends LumberjackLogPayload | void = void> {
    #private;
    constructor(lumberjack: LumberjackService<TPayload>, time: LumberjackTimeService, level: LumberjackLogLevel, message: string);
    build(): (...payloadArg: TPayload extends void ? [never?] : [TPayload]) => void;
    /**
     * Add a scope to the `LumberjackLog`
     */
    withScope(scope: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Add payload with custom data to the `LumberjackLog`
     */
    withPayload(...payloadArg: TPayload extends void ? [never?] : [TPayload]): LumberjackLoggerBuilder;
}

/**
 * A logger holds methods that log a predefined log.
 *
 * Implement application- and library-specific loggers by extending this base
 * class. Optionally supports a log payload.
 *
 * Each protected method on this base class returns a logger builder.
 */
declare abstract class LumberjackLogger<TPayload extends LumberjackLogPayload | void = void> {
    protected readonly lumberjack: LumberjackService<TPayload>;
    protected readonly time: LumberjackTimeService;
    /**
     * Create a logger builder for a critical log with the specified message.
     */
    protected createCriticalLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for a debug log with the specified message.
     */
    protected createDebugLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for an error log with the specified message.
     */
    protected createErrorLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for an info log with the specified message.
     */
    protected createInfoLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for a trace log with the specified message.
     */
    protected createTraceLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for a warning log with the specified message.
     */
    protected createWarningLogger(message: string): LumberjackLoggerBuilder<TPayload>;
    /**
     * Create a logger builder for a log with the specified log level and message.
     */
    protected createLoggerBuilder(level: LumberjackLogLevel, message: string): LumberjackLoggerBuilder<TPayload>;
    static ɵfac: i0.ɵɵFactoryDeclaration<LumberjackLogger<any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<LumberjackLogger<any>>;
}

/**
 * A scoped logger holds methods that log a predefined log sharing a scope.
 *
 * Implement application- and library-specific loggers by extending this base
 * class. Optionally supports a log payload.
 *
 * Each protected method on this base class returns a logger builder with a
 * predefined scope.
 */
declare abstract class ScopedLumberjackLogger<TPayload extends LumberjackLogPayload | void = void> extends LumberjackLogger<TPayload> {
    protected readonly lumberjack: LumberjackService<TPayload>;
    protected readonly time: LumberjackTimeService;
    abstract readonly scope: string;
    /**
     * Create a logger builder for a log with the shared scope as well as the
     * specified log level and message.
     */
    protected createLoggerBuilder(level: LumberjackLogLevel, message: string): LumberjackLoggerBuilder<TPayload>;
    static ɵfac: i0.ɵɵFactoryDeclaration<ScopedLumberjackLogger<any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<ScopedLumberjackLogger<any>>;
}

/**
 * The generic parameter of `LumberjackLogBuilder` is evaluated to this type
 * when the `LumberjackLogBuilder#withPayload` method is used.
 */
type InternalWithStaticPayload = '__LUMBERJACK_INTERNAL_WITH_STATIC_PAYLOAD__' & LumberjackLogPayload;
/**
 * Builder for a log with the specified log level and message.
 *
 * Use this to create a log before passing it to `LumberjackService`.
 */
declare class LumberjackLogBuilder<TPayload extends LumberjackLogPayload | void = void> {
    #private;
    /**
     * Create a log builder with the specified log level and message.
     *
     * @param time Pass the `LumberjackTimeService`. Used for timestamping the log.
     * @param level The log level.
     * @param message The log message.
     */
    constructor(time: LumberjackTimeService, level: LumberjackLogLevel, message: string);
    /**
     * Create a log with the specified properties and timestamp it.
     *
     * @param payloadArg Optional dynamic payload.
     */
    build(...payloadArg: Extract<TPayload, InternalWithStaticPayload> extends never ? [TPayload] : [never?]): LumberjackLog<Exclude<TPayload, InternalWithStaticPayload>>;
    /**
     * Optionally add a static payload to the log.
     */
    withPayload(...payloadArg: TPayload extends void ? [never?] : [TPayload]): LumberjackLogBuilder<InternalWithStaticPayload | TPayload>;
    /**
     * Add a scope to the log.
     */
    withScope(scope: string): LumberjackLogBuilder<TPayload>;
}

/**
 * Factory for a log builder with the specified log level and message.
 *
 * Use this to create a log before passing it to `LumberjackService`.
 *
 * Wraps `LumberjackLogBuilder`, supports dependency injection, and allows reuse
 * so that we don't have to new up log builders and pass `LumberjackTimeService`
 * to them.
 */
declare class LumberjackLogFactory<TPayload extends LumberjackLogPayload | void = void> {
    #private;
    /**
     * Create a log builder for a critical log with the specified message.
     */
    createCriticalLog(message: string): LumberjackLogBuilder<TPayload>;
    /**
     * Create a log builder for a debug log with the specified message.
     */
    createDebugLog(message: string): LumberjackLogBuilder<TPayload>;
    /**
     * Create a log builder for an error log with the specified message.
     */
    createErrorLog(message: string): LumberjackLogBuilder<TPayload>;
    /**
     * Create a log builder for an info log with the specified message.
     */
    createInfoLog(message: string): LumberjackLogBuilder<TPayload>;
    /**
     * Create a log builder for a trace log with the specified message.
     */
    createTraceLog(message: string): LumberjackLogBuilder<TPayload>;
    /**
     * Create a log builder for a warning log with the specified message.
     */
    createWarningLog(message: string): LumberjackLogBuilder<TPayload>;
    static ɵfac: i0.ɵɵFactoryDeclaration<LumberjackLogFactory<any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<LumberjackLogFactory<any>>;
}

export { LumberjackLogBuilder, LumberjackLogFactory, LumberjackLogger, LumberjackService, LumberjackTimeService, ScopedLumberjackLogger, lumberjackConfigToken, lumberjackLogDriverConfigToken, lumberjackLogDriverToken, provideLumberjack };
export type { LumberjackConfig, LumberjackConfigLevels, LumberjackFormatFunction, LumberjackLevel, LumberjackLog, LumberjackLogDriver, LumberjackLogDriverConfig, LumberjackLogDriverLog, LumberjackLogLevel, LumberjackLogPayload, LumberjackOptions };
