import { LoggerlessTransportConfig, LoggerlessTransport, LogLayerTransportParams } from '@loglayer/transport';

interface LogFileRotationCallbacks {
    /**
     * Called when a log file is rotated
     * @param oldFile - The path to the old log file
     * @param newFile - The path to the new log file
     */
    onRotate?: (oldFile: string, newFile: string) => void;
    /**
     * Called when a new log file is created
     * @param newFile - The path to the new log file
     */
    onNew?: (newFile: string) => void;
    /**
     * Called when a log file is opened
     */
    onOpen?: () => void;
    /**
     * Called when a log file is closed
     */
    onClose?: () => void;
    /**
     * Called when an error occurs
     * @param error - The error that occurred
     */
    onError?: (error: Error) => void;
    /**
     * Called when the stream is finished
     */
    onFinish?: () => void;
    /**
     * Called when a log file is removed due to retention policy
     * @param info - Information about the removed log file
     */
    onLogRemoved?: (info: {
        date: number;
        name: string;
        hash: string;
    }) => void;
}
interface LogFileRotationFieldNames {
    /**
     * Field name for the log level
     * @default "level"
     */
    level?: string;
    /**
     * Field name for the log message
     * @default "message"
     */
    message?: string;
    /**
     * Field name for the timestamp
     * @default "timestamp"
     */
    timestamp?: string;
}
interface LogFileRotationLevelMap {
    /**
     * Mapping for the 'fatal' log level
     * @example 60 or "FATAL"
     */
    fatal?: string | number;
    /**
     * Mapping for the 'error' log level
     * @example 50 or "ERROR"
     */
    error?: string | number;
    /**
     * Mapping for the 'warn' log level
     * @example 40 or "WARN"
     */
    warn?: string | number;
    /**
     * Mapping for the 'info' log level
     * @example 30 or "INFO"
     */
    info?: string | number;
    /**
     * Mapping for the 'debug' log level
     * @example 20 or "DEBUG"
     */
    debug?: string | number;
    /**
     * Mapping for the 'trace' log level
     * @example 10 or "TRACE"
     */
    trace?: string | number;
}
interface LogFileRotationBatchConfig {
    /**
     * Maximum number of log entries to queue before writing.
     * Default: 1000
     */
    size?: number;
    /**
     * Maximum time in milliseconds to wait before writing queued logs.
     * Default: 5000 (5 seconds)
     */
    timeout?: number;
}
interface LogFileRotationTransportConfig extends LoggerlessTransportConfig {
    /**
     * The filename pattern to use for the log files.
     * Supports date format using numerical values.
     * Example: "./logs/application-%DATE%.log"
     */
    filename: string;
    /**
     * Static data to be included in every log entry.
     * Can be either:
     * - A function that returns an object containing static data
     * - A direct object containing static data
     *
     * The data will be merged with the log entry before any other data.
     * If using a function, it will be called for each log entry.
     * @example
     * ```typescript
     * // Using a function
     * staticData: () => ({
     *   hostname: hostname(),
     *   pid: process.pid
     * })
     *
     * // Using an object
     * staticData: {
     *   hostname: hostname(),
     *   pid: process.pid
     * }
     * ```
     */
    staticData?: (() => Record<string, any>) | Record<string, any>;
    /**
     * The frequency of rotation. Can be:
     * - 'daily' for daily rotation
     * - 'date' for rotation on date format change
     * - '[1-30]m' for rotation every X minutes
     * - '[1-12]h' for rotation every X hours
     */
    frequency?: string;
    /**
     * The date format to use in the filename.
     * Uses single characters for each date component:
     * - 'Y' for full year
     * - 'M' for month
     * - 'D' for day
     * - 'H' for hour
     * - 'm' for minutes
     * - 's' for seconds
     *
     * Common patterns:
     * - For daily rotation: use "YMD" (creates files like app-20240117.log)
     * - For hourly/minute rotation: use "YMDHm" (creates files like app-202401171430.log)
     *
     * @default "YMD"
     */
    dateFormat?: string;
    /**
     * The size at which to rotate.
     * Examples: "10M", "100K", "100B"
     * If frequency is specified, this will be ignored.
     */
    size?: string;
    /**
     * Maximum number of logs to keep.
     * Can be a number of files or days (e.g., "10d" for 10 days)
     */
    maxLogs?: string | number;
    /**
     * Location to store the log audit file.
     * If not set, it will be stored in the root of the application.
     */
    auditFile?: string;
    /**
     * File extension to be appended to the filename.
     * Useful when using size restrictions as the rotation adds a count at the end.
     */
    extension?: string;
    /**
     * Create a tailable symlink to the current active log file.
     * Default: false
     */
    createSymlink?: boolean;
    /**
     * Name to use when creating the symbolic link.
     * Default: 'current.log'
     */
    symlinkName?: string;
    /**
     * Use UTC time for date in filename.
     * Default: false
     */
    utc?: boolean;
    /**
     * Use specified hashing algorithm for audit.
     * Default: 'md5'
     * Use 'sha256' for FIPS compliance.
     */
    auditHashType?: "md5" | "sha256";
    /**
     * File mode to be used when creating log files.
     * Default: 0o640 (user read/write, group read, others none)
     */
    fileMode?: number;
    /**
     * Options passed to the file stream.
     * See: https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options
     */
    fileOptions?: {
        flags?: string;
        encoding?: string;
        mode?: number;
    };
    /**
     * Event callbacks for various file stream events
     */
    callbacks?: LogFileRotationCallbacks;
    /**
     * Custom field names for the log entry JSON
     * Default: { level: "level", message: "message", data: "data", timestamp: "timestamp" }
     */
    fieldNames?: LogFileRotationFieldNames;
    /**
     * Delimiter between log entries.
     * Default: "\n"
     */
    delimiter?: string;
    /**
     * Custom function to generate timestamps for log entries.
     * Can return either a string (e.g., ISO string) or a number (e.g., Unix timestamp)
     * If not provided, defaults to new Date().toISOString()
     */
    timestampFn?: () => string | number;
    /**
     * Custom mapping for log levels.
     * Each log level can be mapped to either a string or number.
     * Example: { error: 50, warn: 40, info: 30, debug: 20, trace: 10, fatal: 60 }
     * Example: { error: "ERROR", warn: "WARN", info: "INFO", debug: "DEBUG", trace: "TRACE", fatal: "FATAL" }
     */
    levelMap?: LogFileRotationLevelMap;
    /**
     * Whether to compress rotated log files using gzip.
     * When enabled, rotated files will be compressed with .gz extension.
     * Default: false
     */
    compressOnRotate?: boolean;
    /**
     * Whether to enable verbose mode in the underlying file-stream-rotator.
     * When enabled, the rotator will log detailed information about its operations.
     * Default: false
     */
    verbose?: boolean;
    /**
     * Batch processing configuration.
     * If defined, batch processing will be enabled.
     * When batching is enabled, logs are queued in memory and written to disk in batches.
     * Queued logs are automatically flushed in the following situations:
     * - When the batch size is reached
     * - When the batch timeout is reached
     * - When the transport is disposed
     * - When the process exits (including SIGINT and SIGTERM signals)
     */
    batch?: LogFileRotationBatchConfig;
}
/**
 * A transport that writes logs to rotating files with support for time-based and size-based rotation.
 * Features include:
 * - Automatic log file rotation based on time (hourly, daily) or size
 * - Support for date patterns in filenames using numerical values (YYYY, MM, DD, etc.)
 * - Size-based rotation with support for KB, MB, and GB units
 * - Compression of rotated log files using gzip
 * - Maximum file count or age-based retention
 * - Automatic cleanup of old log files
 * - Batch processing of logs for improved performance
 * - Safe handling of process termination signals
 *
 * Each instance must have a unique filename to prevent race conditions.
 * If you need multiple loggers to write to the same file, share the same transport instance between them.
 */
declare class LogFileRotationTransport extends LoggerlessTransport implements Disposable {
    /** Registry of active filenames to prevent multiple transports writing to the same file */
    private static activeFilenames;
    /** The current write stream for the log file */
    private stream;
    /** Custom field names for log entries */
    private fieldNames;
    /** Delimiter between log entries */
    private delimiter;
    /** Function to generate timestamps for log entries */
    private timestampFn;
    /** Custom mapping for log levels */
    private levelMap;
    /** Whether to compress rotated files */
    private compressOnRotate;
    /** Whether a file is currently being compressed */
    private isCompressing;
    /** The base filename pattern for log files */
    private filename;
    /** Static data to be included in every log entry */
    private staticData?;
    /** Whether batch processing is enabled */
    private batchEnabled;
    /** Maximum number of log entries to queue before writing */
    private batchSize;
    /** Maximum time in milliseconds to wait before writing queued logs */
    private batchTimeout;
    /** Queue of log entries waiting to be written */
    private batchQueue;
    /** Timer for batch flush timeout */
    private batchTimer;
    /** Whether the transport is being disposed */
    private isDisposing;
    /** Event callbacks for various file stream events */
    private callbacks?;
    /** Frequency of rotation (daily, hourly, etc.) */
    private frequency?;
    /** Whether to enable verbose mode */
    private verbose?;
    /** Date format for filename patterns */
    private dateFormat?;
    /** Size threshold for rotation */
    private size?;
    /** Maximum number of log files to keep */
    private maxLogs?;
    /** Path to the audit file */
    private auditFile?;
    /** File extension for log files */
    private extension?;
    /** Whether to create a symlink to current log */
    private createSymlink?;
    /** Name of the symlink file */
    private symlinkName?;
    /** Whether to use UTC time in filenames */
    private utc?;
    /** Hash algorithm for audit file */
    private auditHashType?;
    /** Options for file streams */
    private fileOptions?;
    /** File mode to be used when creating log files */
    private fileMode?;
    /**
     * Generates the options for FileStreamRotator consistently across the transport
     * @returns FileStreamRotatorOptions object
     * @private
     */
    private getRotatorOptions;
    /**
     * Creates a new LogFileRotationTransport instance.
     * @param params - Configuration options for the transport
     * @throws {Error} If the filename is already in use by another transport instance
     */
    constructor(params: LogFileRotationTransportConfig);
    /**
     * Initializes the write stream and sets up event listeners.
     * This is called either immediately if batching is disabled,
     * or lazily when the first batch needs to be written if batching is enabled.
     * @param options - Options for the file stream rotator
     * @private
     */
    private initStream;
    /**
     * Generates a unique path for a compressed log file.
     * If a file with .gz extension already exists, appends timestamp and counter.
     * @param filePath - The original log file path
     * @returns The unique path for the compressed file
     * @private
     */
    private getUniqueCompressedFilePath;
    /**
     * Compresses a log file using gzip.
     * @param filePath - Path to the file to compress
     * @returns Path to the compressed file
     * @private
     */
    private compressFile;
    /**
     * Flushes queued log entries to disk asynchronously.
     * This is used for normal batch processing operations.
     * @private
     */
    private flush;
    /**
     * Synchronously flush logs to disk.
     * This is used during process termination (SIGINT/SIGTERM) to ensure logs are written
     * before the process exits. This method uses synchronous file I/O to guarantee that
     * logs are written even during abrupt process termination.
     * @private
     */
    private flushSync;
    /**
     * Schedules a batch flush operation.
     * This creates a timer that will flush the batch after the configured timeout.
     * The timer is unref'd to prevent keeping the process alive.
     * @private
     */
    private scheduleBatchFlush;
    /**
     * Processes and writes a log entry.
     * If batching is enabled, the entry is queued and written based on batch settings.
     * If batching is disabled, the entry is written immediately.
     * @param params - The log entry parameters
     * @returns The original messages array
     */
    shipToLogger({ logLevel, messages, data, hasData }: LogLayerTransportParams): any[];
    /**
     * Disposes of the transport, cleaning up resources and flushing any remaining logs.
     * This method:
     * 1. Prevents new batch flushes from being scheduled
     * 2. Cancels any pending batch flush
     * 3. Flushes any remaining logs
     * 4. Waits for any in-progress compression to complete
     * 5. Closes the write stream
     * 6. Removes the filename from the registry
     */
    [Symbol.dispose](): void;
}

export { type LogFileRotationBatchConfig, type LogFileRotationCallbacks, type LogFileRotationFieldNames, type LogFileRotationLevelMap, LogFileRotationTransport, type LogFileRotationTransportConfig };
