import { Instance } from 'ink';
import { FormattedKeyValue, InfoBlock, KeyValuePair, SimpleMessage, StageInfoBlock, StagesProps } from './components/stages.js';
import { Design, RequiredDesign } from './design.js';
import { StageStatus, StageTracker } from './stage-tracker.js';
export type MultiStageOutputOptions<T extends Record<string, unknown>> = {
    /**
     * Stages to render.
     */
    readonly stages: readonly string[] | string[];
    /**
     * Title to display at the top of the stages component.
     */
    readonly title?: string;
    /**
     * Information to display at the bottom of the stages component.
     */
    readonly postStagesBlock?: Array<KeyValuePair<T> | SimpleMessage<T>>;
    /**
     * Information to display below the title but above the stages.
     */
    readonly preStagesBlock?: Array<KeyValuePair<T> | SimpleMessage<T>>;
    /**
     * Whether to show the total elapsed time. Defaults to true
     */
    readonly showElapsedTime?: boolean;
    /**
     * Whether to show the time spent on each stage. Defaults to true
     */
    readonly showStageTime?: boolean;
    /**
     * Whether to show the title. Defaults to true
     */
    readonly showTitle?: boolean;
    /**
     * Information to display for a specific stage. Each object must have a stage property set.
     */
    readonly stageSpecificBlock?: StageInfoBlock<T>;
    /**
     * The unit to use for the timer. Defaults to 'ms'
     */
    readonly timerUnit?: 'ms' | 's';
    /**
     * Data to display in the stages component. This data will be passed to the get function in the info object.
     */
    readonly data?: Partial<T>;
    /**
     * Design options to customize the output.
     */
    readonly design?: Design;
    /**
     * Set to true when --json flag is passed to the command. This will prevent any output to the console. Defaults to false
     */
    readonly jsonEnabled: boolean;
};
declare class CIMultiStageOutput<T extends Record<string, unknown>> {
    private readonly completedStages;
    private data?;
    private readonly design;
    private readonly hasElapsedTime?;
    private readonly hasStageTime?;
    /**
     * Amount of time (in milliseconds) between heartbeat updates
     */
    private readonly heartbeat;
    /**
     * Time of the last heartbeat
     */
    private lastHeartbeatTime;
    /**
     * Map of the last time a specific piece of info was updated. This is used for throttling messages
     */
    private readonly lastUpdateByInfo;
    private readonly postStagesBlock?;
    private readonly preStagesBlock?;
    private readonly seenStrings;
    private readonly stages;
    private readonly stageSpecificBlock?;
    private readonly startTime;
    private readonly startTimes;
    /**
     * Amount of time (in milliseconds) between throttled updates
     */
    private readonly throttle;
    private readonly timerUnit;
    /**
     * Map of intervals used to trigger heartbeat updates
     */
    private readonly updateIntervals;
    constructor({ data, design, postStagesBlock, preStagesBlock, showElapsedTime, showStageTime, stages, stageSpecificBlock, timerUnit, title, }: MultiStageOutputOptions<T>);
    stop(stageTracker: StageTracker): void;
    update(stageTracker: StageTracker, data?: Partial<T>): void;
    private maybePrintInfo;
    private maybeStdout;
}
declare class MultiStageOutputBase<T extends Record<string, unknown>> implements Disposable {
    protected readonly ciInstance: CIMultiStageOutput<T> | undefined;
    protected data?: Partial<T>;
    protected readonly design: RequiredDesign;
    protected readonly hasElapsedTime?: boolean;
    protected readonly hasStageTime?: boolean;
    protected readonly inkInstance: Instance | undefined;
    protected readonly postStagesBlock?: InfoBlock<T>;
    protected readonly preStagesBlock?: InfoBlock<T>;
    protected readonly stages: readonly string[] | string[];
    protected readonly stageSpecificBlock?: StageInfoBlock<T>;
    protected readonly stageTracker: StageTracker;
    protected stopped: boolean;
    protected readonly timerUnit?: 'ms' | 's';
    protected readonly title?: string;
    constructor({ data, design, jsonEnabled, postStagesBlock, preStagesBlock, showElapsedTime, showStageTime, stages, stageSpecificBlock, timerUnit, title, }: MultiStageOutputOptions<T>, allowParallelTasks?: boolean);
    /**
     * Stop multi-stage output from running with a failed status.
     */
    error(): void;
    protected formatKeyValuePairs(infoBlock: InfoBlock<T> | StageInfoBlock<T> | undefined): FormattedKeyValue[];
    /** shared method to populate everything needed for Stages cmp */
    protected generateStagesInput(opts?: {
        compactionLevel?: number;
    }): StagesProps;
    protected rerender(): void;
    /**
     * Stop multi-stage output from running.
     *
     * The stage currently running will be changed to the provided `finalStatus`.
     *
     * @param finalStatus - The status to set the current stage to.
     * @returns void
     */
    stop(finalStatus?: StageStatus): void;
    [Symbol.dispose](): void;
    /**
     * Updates the data of the component.
     *
     * @param data - The partial data object to update the component's data with.
     * @returns void
     */
    updateData(data: Partial<T>): void;
}
export declare class MultiStageOutput<T extends Record<string, unknown>> extends MultiStageOutputBase<T> {
    constructor(options: MultiStageOutputOptions<T>);
    /**
     * Go to a stage, marking any stages in between the current stage and the provided stage as completed.
     *
     * If the stage does not exist or is before the current stage, nothing will happen.
     *
     * If the stage is the same as the current stage, the data will be updated.
     *
     * @param stage Stage to go to
     * @param data - Optional data to pass to the next stage.
     * @returns void
     */
    goto(stage: string, data?: Partial<T>): void;
    /**
     * Moves to the next stage of the process.
     *
     * @param data - Optional data to pass to the next stage.
     * @returns void
     */
    next(data?: Partial<T>): void;
    /**
     * Go to a stage, marking any stages in between the current stage and the provided stage as skipped.
     *
     * If the stage does not exist or is before the current stage, nothing will happen.
     *
     * If the stage is the same as the current stage, the data will be updated.
     *
     * @param stage Stage to go to
     * @param data - Optional data to pass to the next stage.
     * @returns void
     */
    skipTo(stage: string, data?: Partial<T>): void;
    private update;
}
export declare class ParallelMultiStageOutput<T extends Record<string, unknown>> extends MultiStageOutputBase<T> {
    constructor(options: MultiStageOutputOptions<T>);
    pauseStage(stage: string, data?: Partial<T>): void;
    resumeStage(stage: string, data?: Partial<T>): void;
    startStage(stage: string, data?: Partial<T>): void;
    stopStage(stage: string, data?: Partial<T>): void;
    updateStage(stage: string, status: StageStatus, data?: Partial<T>): void;
    private update;
}
export {};
