import { IGitExtensionService } from '../../../platform/git/common/gitExtensionService';
import { DebugRecorderBookmark } from '../../../platform/inlineEdits/common/debugRecorderBookmark';
import { IObservableDocument, ObservableWorkspace } from '../../../platform/inlineEdits/common/observableWorkspace';
import { IStatelessNextEditTelemetry, StatelessNextEditRequest } from '../../../platform/inlineEdits/common/statelessNextEditProvider';
import { INotebookService } from '../../../platform/notebook/common/notebookService';
import { ITelemetryService } from '../../../platform/telemetry/common/telemetry';
import { IWorkspaceService } from '../../../platform/workspace/common/workspaceService';
import { LogEntry } from '../../../platform/workspaceRecorder/common/workspaceLog';
import { Disposable, IDisposable } from '../../../util/vs/base/common/lifecycle';
import { StringReplacement } from '../../../util/vs/editor/common/core/edits/stringEdit';
import { DebugRecorder } from './debugRecorder';
import { INesConfigs } from './nesConfigs';
import { INextEditDisplayLocation, INextEditResult } from './nextEditResult';
export type NextEditTelemetryStatus = 'new' | 'requested' | `noEdit:${string}` | 'docChanged' | 'emptyEdits' | 'emptyEditsButHasNextCursorPosition' | 'previouslyRejected' | 'previouslyRejectedCache' | 'accepted' | 'notAccepted' | 'rejected';
export type NesAcceptance = 'accepted' | 'notAccepted' | 'rejected';
export type EnhancedTelemetrySendingReasonKind = 'idle' | 'hard_cap' | 'user_jump';
export interface IEnhancedTelemetrySendingReason {
    readonly reason: EnhancedTelemetrySendingReasonKind;
    readonly details: {
        readonly idleTimeoutMs?: number;
        readonly hardCapTimeoutMs?: number;
        readonly from?: {
            readonly file: string;
            readonly line: number;
        };
        readonly to?: {
            readonly file: string;
            readonly line: number | undefined;
        };
    };
}
export interface IAlternativeAction {
    readonly text: string | undefined;
    readonly textLength: number;
    readonly selection: ITelemetryRange[];
    readonly edits: ITelemetryEdit[];
    readonly tags: string[];
    readonly recording: ITelemetryRecording | undefined;
}
export interface ITelemetryEdit {
    readonly time: string;
    readonly start: number;
    readonly endExclusive: number;
    readonly newText: string;
}
export interface ITelemetryRange {
    readonly start: number;
    readonly endExclusive: number;
}
export interface ITelemetryRecording {
    readonly entries: LogEntry[] | undefined;
    readonly entriesSize: number;
    readonly requestTime: number;
}
export declare const enum ReusedRequestKind {
    Speculative = "speculative",
    Async = "async"
}
export interface ILlmNESTelemetry extends Partial<IStatelessNextEditTelemetry> {
    readonly providerId: string;
    readonly headerRequestId: string | undefined;
    readonly nextEditProviderDuration: number | undefined;
    readonly fetchStartedAfterMs: number | undefined;
    readonly isFromCache: boolean;
    readonly reusedRequest: ReusedRequestKind | undefined;
    readonly subsequentEditOrder: number | undefined;
    readonly activeDocumentOriginalLineCount: number | undefined;
    readonly activeDocumentEditsCount: number | undefined;
    readonly activeDocumentLanguageId: string | undefined;
    readonly activeDocumentRepository: string | undefined;
    readonly hasNextEdit: boolean;
    readonly wasPreviouslyRejected: boolean;
    readonly status: NextEditTelemetryStatus;
    readonly nextEditProviderError: string | undefined;
    readonly nesConfigs: INesConfigs | undefined;
    readonly repositoryUrls: string[] | undefined;
    readonly documentsCount: number | undefined;
    readonly editsCount: number | undefined;
    readonly isNotebook: boolean;
    readonly notebookType: string | undefined;
    readonly alternativeAction: IAlternativeAction | undefined;
}
export interface IDiagnosticsTelemetry {
    readonly diagnosticType: string | undefined;
    readonly diagnosticDroppedReasons: string | undefined;
    readonly diagnosticDistanceToUnknownDiagnostic: number | undefined;
    readonly diagnosticDistanceToAlternativeDiagnostic: number | undefined;
    readonly diagnosticHasAlternativeDiagnosticForSameRange: boolean | undefined;
    readonly diagnosticHasExistingSameFileImport: boolean | undefined;
    readonly diagnosticIsLocalImport: boolean | undefined;
    readonly diagnosticAlternativeImportsCount: number | undefined;
}
export interface INextEditProviderTelemetry extends ILlmNESTelemetry, IDiagnosticsTelemetry {
    readonly opportunityId: string;
    readonly requestN: number;
    readonly isShown: boolean;
    readonly acceptance: NesAcceptance;
    readonly disposalReason: string | undefined;
    readonly supersededByOpportunityId: string | undefined;
    readonly status: NextEditTelemetryStatus;
    readonly nextEditProviderError: string | undefined;
    readonly activeDocumentRepository: string | undefined;
    readonly repositoryUrls: string[] | undefined;
    readonly alternativeAction: IAlternativeAction | undefined;
    readonly postProcessingOutcome: string | undefined;
    readonly isNESForAnotherDoc: boolean;
    readonly notebookCellMarkerCount: number;
    readonly notebookCellMarkerIndex: number;
    readonly notebookId: string | undefined;
    readonly notebookCellLines: string | undefined;
    readonly isActiveDocument?: boolean;
    readonly isMultilineEdit?: boolean;
    readonly isEolDifferent?: boolean;
    readonly isNextEditorVisible?: boolean;
    readonly isNextEditorRangeVisible?: boolean;
    readonly isNaturalLanguageDominated: boolean;
    readonly hadLlmNES: boolean;
    readonly hadDiagnosticsNES: boolean;
    readonly pickedNES: 'llm' | 'diagnostics' | undefined;
    readonly configIsDiagnosticsNESEnabled: boolean;
    readonly userTypingDisagreed: boolean | undefined;
}
export declare class LlmNESTelemetryBuilder extends Disposable {
    private readonly _gitExtensionService;
    private readonly _notebookService;
    private readonly _workspaceService;
    private readonly _providerId;
    private readonly _doc;
    private readonly _debugRecorder?;
    private readonly _requestBookmark?;
    build(includeAlternativeAction: boolean): ILlmNESTelemetry;
    private _startTime;
    /** Dependent on the observable document to track edits and selections */
    private editCollectingInfo;
    get originalSelectionLine(): number | undefined;
    /**
     * @param _doc passing an observable document allows to track edits and selections
     */
    constructor(_gitExtensionService: IGitExtensionService | undefined, _notebookService: INotebookService | undefined, _workspaceService: IWorkspaceService | undefined, _providerId: string, _doc: IObservableDocument | undefined, _debugRecorder?: DebugRecorder | undefined, _requestBookmark?: DebugRecorderBookmark | undefined);
    private _nesConfigs;
    setNESConfigs(nesConfigs: INesConfigs): this;
    private _headerRequestId;
    setHeaderRequestId(uuid: string): this;
    private _isFromCache;
    setIsFromCache(): this;
    private _reusedRequest;
    setReusedRequest(kind: ReusedRequestKind): this;
    private _subsequentEditOrder;
    setSubsequentEditOrder(subsequentEditOrder: number | undefined): this;
    private _request;
    setRequest(request: StatelessNextEditRequest): this;
    private _statelessNextEditTelemetry;
    setStatelessNextEditTelemetry(statelessNextEditTelemetry: IStatelessNextEditTelemetry): this;
    private _hasNextEdit;
    setHasNextEdit(hasNextEdit: boolean): this;
    private _wasPreviouslyRejected;
    setWasPreviouslyRejected(): this;
    private _duration;
    markEndTime(): this;
    private _status;
    setStatus(status: NextEditTelemetryStatus): this;
    private _nextEditProviderError;
    setNextEditProviderError(nextEditProviderError: string | undefined): this;
}
interface IDiagnosticTelemetryRun {
    alternativeImportsCount?: number;
    hasExistingSameFileImport?: boolean;
    isLocalImport?: boolean;
    distanceToUnknownDiagnostic?: number;
    distanceToAlternativeDiagnostic?: number;
    hasAlternativeDiagnosticForSameRange?: boolean;
}
export declare class DiagnosticsTelemetryBuilder {
    build(): IDiagnosticsTelemetry;
    populate(telemetry: DiagnosticsTelemetryBuilder): void;
    private _type;
    setType(type: string): this;
    private _droppedReasons;
    addDroppedReason(reason: string): this;
    private _diagnosticRunTelemetry;
    setDiagnosticRunTelemetry(diagnosticRun: IDiagnosticTelemetryRun): this;
}
export declare class NextEditProviderTelemetryBuilder extends Disposable {
    readonly doc: IObservableDocument | undefined;
    private static providerIdToReqN;
    /**
     * Whether telemetry for this builder has been sent -- only for ordinary telemetry, not enhanced telemetry
     */
    private _isSent;
    get isSent(): boolean;
    markAsSent(): void;
    build(includeAlternativeAction: boolean): INextEditProviderTelemetry;
    private _requestN;
    private readonly _nesBuilder;
    get nesBuilder(): LlmNESTelemetryBuilder;
    private readonly _diagnosticsBuilder;
    get diagnosticsBuilder(): DiagnosticsTelemetryBuilder;
    /**
     * @param _doc passing an observable document allows to track edits and selections
     */
    constructor(gitExtensionService: IGitExtensionService | undefined, notebookService: INotebookService | undefined, workspaceService: IWorkspaceService | undefined, providerId: string, doc: IObservableDocument | undefined, debugRecorder?: DebugRecorder, requestBookmark?: DebugRecorderBookmark);
    private _opportunityId;
    setOpportunityId(uuid: string): this;
    private _isShown;
    setAsShown(): this;
    private _acceptance;
    setAcceptance(acceptance: NesAcceptance): this;
    private _disposalReason;
    setDisposalReason(disposalReason: string | undefined): this;
    private _supersededByOpportunityId;
    setSupersededBy(opportunityId: string | undefined): this;
    private _userTypingDisagreed;
    setUserTypingDisagreed(userTypingDisagreed: boolean): this;
    private _nesTypePicked;
    setPickedNESType(nesTypePicked: 'llm' | 'diagnostics'): this;
    private _isActiveDocument?;
    setIsActiveDocument(isActive: boolean): this;
    private _notebookCellMarkerCount;
    setNotebookCellMarkerCount(count: number): this;
    private _isMultilineEdit?;
    setIsMultilineEdit(isMultiLine: boolean): this;
    private _isEolDifferent?;
    setIsEolDifferent(isEolDifferent: boolean): this;
    private _isNextEditorVisible?;
    setIsNextEditorVisible(isVisible: boolean): this;
    private _isNextEditorRangeVisible?;
    setIsNextEditorRangeVisible(isVisible: boolean): this;
    private _notebookId?;
    setNotebookId(notebookId: string): this;
    private _notebookCellLines?;
    setNotebookCellLines(notebookCellLines: string): this;
    private _notebookCellMarkerIndex;
    setNotebookCellMarkerIndex(index: number): this;
    private _isNESForAnotherDoc;
    setIsNESForOtherEditor(isForAnotherDoc: boolean): this;
    private _hadLlmNES;
    setHadLlmNES(boolean: boolean): this;
    private _hadDiagnosticsNES;
    setHadDiagnosticsNES(boolean: boolean): this;
    setStatus(status: NextEditTelemetryStatus): this;
    private _configIsDiagnosticsNESEnabled;
    setConfigIsDiagnosticsNESEnabled(boolean: boolean): this;
    private _isNaturalLanguageDominated;
    setIsNaturalLanguageDominated(isNaturalLanguageDominated: boolean): this;
    private _postProcessingOutcome;
    setPostProcessingOutcome(suggestion: {
        edit: StringReplacement;
        isInlineCompletion: boolean;
        displayLocation?: INextEditDisplayLocation;
    }): this;
}
export declare class TelemetrySender implements IDisposable {
    private readonly _workspace;
    private readonly _telemetryService;
    private readonly _map;
    private _idleDetector;
    constructor(_workspace: ObservableWorkspace | undefined, _telemetryService: ITelemetryService);
    /**
     * Schedule sending enhanced telemetry for a NES suggestion.
     *
     * After a 2-minute initial delay, enters an idle-detection phase that monitors all workspace documents
     * and finally sends the telemetry event when one of these conditions is met:
     *
     * - **idle** (5s): No document edits across the entire workspace for 5 seconds.
     * - **user_jump**: User moves cursor to a different line or different file (detected via
     *   {@link IObservableDocument.primarySelectionLine} snapshot diffs.
     * - **hard_cap** (30s): Forced send after 30 seconds regardless of activity.
     *
     * Note: only documents tracked by the {@link ObservableWorkspace} are monitored. Documents in
     * languages where Copilot completions are disabled (e.g. markdown) and copilot-ignored files are excluded,
     * so activity in those files won't reset the idle timer. This matches the scope of {@link DebugRecorder}.
     */
    scheduleSendingEnhancedTelemetry(nextEditResult: INextEditResult, builder: NextEditProviderTelemetryBuilder): void;
    private _enterIdleDetection;
    private _releaseIdleDetector;
    /** Send all entries that are in the idle-detection phase (have no initial timeout pending) with a shared reason. */
    private _sendAllPendingInIdlePhase;
    /** Send all entries in idle-detection phase with user_jump, using per-entry `from` positions. */
    private _sendAllPendingInIdlePhaseWithJump;
    /** Send enhanced telemetry for a single entry that's in the idle-detection phase. */
    private _sendForEntry;
    private _removeEntry;
    private _buildAndSendEnhancedTelemetry;
    /**
     * Send telemetry for the next edit result in case it has already been rejected or contains no edits to be shown.
     */
    sendTelemetry(nextEditResult: INextEditResult | undefined, builder: NextEditProviderTelemetryBuilder): void;
    sendTelemetryForBuilder(builder: NextEditProviderTelemetryBuilder): void;
    private _doSendTelemetry;
    private _sendTelemetryToBoth;
    private _doSendEnhancedTelemetry;
    /**
     * If `value` is undefined, return undefined, otherwise return 1 if `value` is true, 0 otherwise.
     */
    private _boolToNum;
    dispose(): void;
}
export {};
//# sourceMappingURL=nextEditProviderTelemetry.d.ts.map