import { DisposableSymbols } from '@whatwg-node/disposablestack';

type MaybeLazy<T> = T | (() => T);
type AttributeValue = any;
type Attributes = AttributeValue[] | {
    [key: string | number]: AttributeValue;
};

declare function jsonStringify(val: unknown, pretty?: boolean): string;
interface LogWriter {
    write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void | Promise<void>;
}

type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
interface LoggerOptions {
    /**
     * The minimum log level to log.
     *
     * Providing `false` will disable all logging.
     *
     * Provided function will always be invoked to get the current log level.
     *
     * @default env.LOG_LEVEL || env.DEBUG ? 'debug' : 'info'
     */
    level?: MaybeLazy<LogLevel | false>;
    /** A prefix to include in every log's message. */
    prefix?: string;
    /**
     * The attributes to include in all logs. Is mainly used to pass the parent
     * attributes when creating {@link Logger.child child loggers}.
     */
    attrs?: Attributes;
    /**
     * The log writers to use when writing logs.
     *
     * @default env.LOG_JSON ? [new JSONLogWriter()] : [new ConsoleLogWriter()]
     */
    writers?: [LogWriter, ...LogWriter[]];
}
declare class Logger implements AsyncDisposable {
    #private;
    constructor(opts?: LoggerOptions);
    /** The prefix that's prepended to each log message. */
    get prefix(): string | undefined;
    /**
     * The attributes that are added to each log. If the log itself contains
     * attributes with keys existing in {@link attrs}, the log's attributes will
     * override.
     */
    get attrs(): Attributes | undefined;
    /** The current {@link LogLevel} of the logger. You can change the level using the {@link setLevel} method. */
    get level(): false | LogLevel;
    /**
     * Sets the new {@link LogLevel} of the logger. All subsequent logs, and {@link child child loggers} whose
     * level did not change, will respect the new level.
     */
    setLevel(level: MaybeLazy<LogLevel | false>): void;
    write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void;
    flush(): Promise<void> | undefined;
    [DisposableSymbols.asyncDispose](): Promise<void | undefined>;
    child(prefix: string): Logger;
    child(attrs: Attributes, prefix?: string): Logger;
    log(level: LogLevel): void;
    log(level: LogLevel, attrs: MaybeLazy<Attributes>): void;
    log(level: LogLevel, msg: string, ...interpol: unknown[]): void;
    log(level: LogLevel, attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    trace(): void;
    trace(attrs: MaybeLazy<Attributes>): void;
    trace(msg: string, ...interpol: unknown[]): void;
    trace(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    debug(): void;
    debug(attrs: MaybeLazy<Attributes>): void;
    debug(msg: string, ...interpol: unknown[]): void;
    debug(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    info(): void;
    info(attrs: MaybeLazy<Attributes>): void;
    info(msg: string, ...interpol: unknown[]): void;
    info(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    warn(): void;
    warn(attrs: MaybeLazy<Attributes>): void;
    warn(msg: string, ...interpol: unknown[]): void;
    warn(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    error(): void;
    error(attrs: MaybeLazy<Attributes>): void;
    error(msg: string, ...interpol: unknown[]): void;
    error(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
}

export { type Attributes as A, type LogWriter as L, type LogLevel as a, Logger as b, type LoggerOptions as c, jsonStringify as j };
