import { Raw } from '@vscode/prompt-tsx';
import { Result } from '../../../util/common/result';
import { DeferredPromise } from '../../../util/vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from '../../../util/vs/base/common/cancellation';
import { URI } from '../../../util/vs/base/common/uri';
import { LineEdit, LineReplacement, SerializedLineEdit } from '../../../util/vs/editor/common/core/edits/lineEdit';
import { StringEdit } from '../../../util/vs/editor/common/core/edits/stringEdit';
import { OffsetRange } from '../../../util/vs/editor/common/core/ranges/offsetRange';
import { StringText } from '../../../util/vs/editor/common/core/text/abstractText';
import { ChatFetchResponseType, FetchResponse } from '../../chat/common/commonTypes';
import { ISerializedOffsetRange, LogEntry } from '../../workspaceRecorder/common/workspaceLog';
import { DocumentId } from './dataTypes/documentId';
import { Edits } from './dataTypes/edit';
import { SerializedEdit } from './dataTypes/editUtils';
import { LanguageId } from './dataTypes/languageId';
import { DebugRecorderBookmark } from './debugRecorderBookmark';
import { InlineEditRequestLogContext } from './inlineEditLogContext';
import { IXtabHistoryEntry } from './workspaceEditTracker/nesXtabHistoryTracker';
import { Position } from '../../../util/vs/editor/common/core/position';
export declare const enum ShowNextEditPreference {
    Always = "always",
    AroundEdit = "aroundEdit"
}
export type PushEdit = (edit: Result<{
    edit: LineReplacement;
    window?: OffsetRange;
    targetDocument?: DocumentId;
    showLabel?: boolean;
}, NoNextEditReason>) => void;
export interface IStatelessNextEditProvider {
    readonly ID: string;
    readonly dependsOnSelection?: boolean;
    readonly showNextEditPreference?: ShowNextEditPreference;
    provideNextEdit(request: StatelessNextEditRequest, pushEdit: PushEdit, logContext: InlineEditRequestLogContext, cancellationToken: CancellationToken): Promise<StatelessNextEditResult>;
    handleAcceptance?(): void;
    handleRejection?(): void;
}
export declare class StatelessNextEditRequest<TFirstEdit = any> {
    readonly id: string;
    readonly opportunityId: string;
    readonly documentBeforeEdits: StringText;
    readonly documents: readonly StatelessNextEditDocument[];
    readonly activeDocumentIdx: number;
    readonly xtabEditHistory: readonly IXtabHistoryEntry[];
    readonly firstEdit: DeferredPromise<Result<TFirstEdit, NoNextEditReason>>;
    readonly expandedEditWindowNLines: number | undefined;
    readonly logContext: InlineEditRequestLogContext;
    readonly recordingBookmark: DebugRecorderBookmark | undefined;
    readonly recording: LogEntry[] | undefined;
    readonly providerRequestStartDateTime: number | undefined;
    private static ID;
    readonly seqid: string;
    readonly cancellationTokenSource: CancellationTokenSource;
    liveDependentants: number;
    fetchIssued: boolean;
    intermediateUserEdit: StringEdit | undefined;
    private readonly _result;
    get result(): Promise<StatelessNextEditResult>;
    constructor(id: string, opportunityId: string, documentBeforeEdits: StringText, documents: readonly StatelessNextEditDocument[], activeDocumentIdx: number, xtabEditHistory: readonly IXtabHistoryEntry[], firstEdit: DeferredPromise<Result<TFirstEdit, NoNextEditReason>>, expandedEditWindowNLines: number | undefined, logContext: InlineEditRequestLogContext, recordingBookmark: DebugRecorderBookmark | undefined, recording: LogEntry[] | undefined, providerRequestStartDateTime: number | undefined);
    setResult(nextEditResult: StatelessNextEditResult): void;
    setResultError(err: any): void;
    hasDocument(docId: DocumentId): boolean;
    getActiveDocument(): StatelessNextEditDocument;
    serialize(): ISerializedNextEditRequest;
    toString(): string;
    toMarkdown(): string;
}
export interface ISerializedNextEditRequest {
    id: string;
    documents: ISerializedNextEditDocument[];
    activeDocumentIdx: number;
    recording: LogEntry[] | undefined;
}
export declare class StatelessNextEditDocument {
    readonly id: DocumentId;
    readonly workspaceRoot: URI | undefined;
    readonly languageId: LanguageId;
    readonly documentLinesBeforeEdit: string[];
    readonly recentEdit: LineEdit;
    readonly documentBeforeEdits: StringText;
    readonly recentEdits: Edits;
    readonly lastSelectionInAfterEdit: OffsetRange | undefined;
    readonly documentAfterEdits: StringText;
    readonly documentAfterEditsLines: string[];
    /**
     * NOTE: if you add new public fields to this class, please also update {@link ISerializedNextEditDocument} and {@link serialize()} methods,
     * which are used to send this to http-server-powered NES provider.
     */
    constructor(id: DocumentId, workspaceRoot: URI | undefined, languageId: LanguageId, documentLinesBeforeEdit: string[], recentEdit: LineEdit, documentBeforeEdits: StringText, recentEdits: Edits, lastSelectionInAfterEdit?: OffsetRange | undefined);
    serialize(): ISerializedNextEditDocument;
    toString(): string;
    toMarkdown(): string;
}
export interface ISerializedNextEditDocument {
    id: string;
    workspaceRoot: string | undefined;
    languageId: string;
    documentLinesBeforeEdit: string[];
    recentEdit: SerializedLineEdit;
    documentBeforeEdits: string;
    recentEdits: SerializedEdit[];
    lastSelectionInAfterEdit: ISerializedOffsetRange | undefined;
}
export declare enum FilteredOutReason {
    LowLogProbSuggestions = "lowLogProbSuggestions",
    EnforcingNextEditOptions = "enforcingNextEditOptions",
    PromptTooLarge = "promptTooLarge",
    Uncategorized = "uncategorized"
}
export declare namespace NoNextEditReason {
    class ActiveDocumentHasNoEdits {
        readonly kind = "activeDocumentHasNoEdits";
    }
    class NoSuggestions {
        readonly documentBeforeEdits: StringText;
        readonly window: OffsetRange | undefined;
        readonly nextCursorPosition?: Position | undefined;
        readonly kind = "noSuggestions";
        constructor(documentBeforeEdits: StringText, window: OffsetRange | undefined, nextCursorPosition?: Position | undefined);
    }
    class GotCancelled {
        readonly message: 'afterDebounce' | 'afterGettingEndpoint' | 'afterLanguageContextAwait' | 'afterPromptConstruction' | 'afterFetchCall' | 'duringStreaming' | 'afterResponse' | 'afterFailedRebase' | 'beforeExecutingNewRequest';
        readonly kind = "gotCancelled";
        constructor(message: 'afterDebounce' | 'afterGettingEndpoint' | 'afterLanguageContextAwait' | 'afterPromptConstruction' | 'afterFetchCall' | 'duringStreaming' | 'afterResponse' | 'afterFailedRebase' | 'beforeExecutingNewRequest');
    }
    class FetchFailure {
        readonly error: Error;
        readonly kind = "fetchFailure";
        constructor(error: Error);
    }
    class FilteredOut {
        readonly message: FilteredOutReason | string;
        readonly kind = "filteredOut";
        constructor(message: FilteredOutReason | string);
    }
    class PromptTooLarge {
        readonly message: 'editWindow' | 'currentFile' | 'final';
        readonly kind = "promptTooLarge";
        constructor(message: 'editWindow' | 'currentFile' | 'final');
    }
    class Uncategorized {
        readonly error: Error;
        readonly kind = "uncategorized";
        constructor(error: Error);
    }
    class Unexpected {
        readonly error: Error;
        readonly kind = "unexpected";
        constructor(error: Error);
    }
}
export type NoNextEditReason = NoNextEditReason.ActiveDocumentHasNoEdits | NoNextEditReason.NoSuggestions | NoNextEditReason.GotCancelled | NoNextEditReason.FetchFailure | NoNextEditReason.FilteredOut | NoNextEditReason.PromptTooLarge | NoNextEditReason.Uncategorized | NoNextEditReason.Unexpected;
export declare class StatelessNextEditResult {
    readonly nextEdit: Result<void, NoNextEditReason>;
    readonly telemetry: IStatelessNextEditTelemetry;
    static noEdit(reason: NoNextEditReason, telemetryBuilder: StatelessNextEditTelemetryBuilder): StatelessNextEditResult;
    static streaming(telemetryBuilder: StatelessNextEditTelemetryBuilder): StatelessNextEditResult;
    constructor(nextEdit: Result<void, NoNextEditReason>, telemetry: IStatelessNextEditTelemetry);
}
export interface IStatelessNextEditTelemetry {
    readonly hadStatelessNextEditProviderCall: boolean;
    readonly statelessNextEditProviderDuration: number;
    readonly isCursorAtEndOfLine: boolean | undefined;
    readonly nLinesOfCurrentFileInPrompt: number | undefined;
    readonly modelName: string | undefined;
    readonly logProbThreshold: number | undefined;
    readonly prompt: string | undefined;
    readonly promptLineCount: number | undefined;
    readonly promptCharCount: number | undefined;
    readonly mergeConflictExpanded: 'normal' | 'only' | undefined;
    readonly debounceTime: number | undefined;
    /** This's only used to compute time from inline edit provider call to fetch init. Not included in telemetry. */
    readonly fetchStartedAt: number | undefined;
    /** Artificial delay (aka backoff) on the response based on previous user acceptance/rejection in milliseconds */
    readonly artificialDelay: number | undefined;
    readonly hadLowLogProbSuggestion: boolean | undefined;
    readonly response: undefined | Promise<FetchResultWithStats>;
    readonly nEditsSuggested: number | undefined;
    readonly lineDistanceToMostRecentEdit: number | undefined;
    readonly nextEditLogprob: number | undefined;
    readonly noNextEditReasonKind: string | undefined;
    readonly noNextEditReasonMessage: string | undefined;
    readonly nextCursorLineError: string | undefined;
    /** nextCursorLineNumber - currentCursorLineNumber */
    readonly nextCursorLineDistance: number | undefined;
}
export type FetchResultWithStats = {
    readonly ttft: number | undefined;
    readonly response: FetchResponse<string>;
    readonly fetchTime: number;
    readonly fetchResult: ChatFetchResponseType;
};
export declare class StatelessNextEditTelemetryBuilder {
    readonly startTime: number;
    readonly requestUuid: string;
    /**
     * It takes a request to automatically capture some properties from the request.
     */
    constructor(request: StatelessNextEditRequest);
    build(result: Result<void, NoNextEditReason>): IStatelessNextEditTelemetry;
    private _logProbThreshold;
    setLogProbThreshold(logProbThreshold: number): this;
    private _mergeConflictExpanded;
    setMergeConflictExpanded(mergeConflictExpanded: 'normal' | 'only'): this;
    private _hadLowLogProbSuggestion;
    setHadLowLogProbSuggestion(hadLowLogProbSuggestions: boolean): this;
    private _nLinesOfCurrentFileInPrompt;
    setNLinesOfCurrentFileInPrompt(nLines: number): this;
    private _modelName;
    setModelName(modelName: string): this;
    private _prompt;
    setPrompt(prompt: Raw.ChatMessage[]): this;
    private _isCursorAtLineEnd;
    setIsCursorAtLineEnd(isCursorAtLineEnd: boolean): this;
    private _debounceTime;
    setDebounceTime(debounceTime: number): this;
    private _artificialDelay;
    setArtificialDelay(artificialDelay: number): this;
    private _fetchStartedAt;
    setFetchStartedAt(): this;
    get fetchStartedAt(): number | undefined;
    private _response;
    setResponse(response: Promise<{
        ttft: number | undefined;
        response: FetchResponse<string>;
    }>): this;
    private _nextEditLogProb;
    setNextEditLogProb(logProb: number): this;
    private _nEditsSuggested;
    setNEditsSuggested(nEditsSuggested: number): this;
    private _lineDistanceToMostRecentEdit;
    setLineDistanceToMostRecentEdit(distanceToMostRecentEdit: number): this;
    private _nextCursorLineError;
    setNextCursorLineError(error: string): this;
    private _nextCursorLineDistance;
    /**
     * nextCursorLineNumber - currentCursorLineNumber
     */
    setNextCursorLineDistance(distance: number): this;
}
//# sourceMappingURL=statelessNextEditProvider.d.ts.map