import { RequestId } from '../../../../../platform/networking/common/fetch';
import { ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
import { ICompletionsTelemetryService } from '../../bridge/src/completionsTelemetryServiceBridge';
import { ExpConfig } from './experiments/expConfig';
import { FilterSettings } from './experiments/filters';
import { APIJsonData } from './openai/openai';
import { Prompt } from './prompt/prompt';
import { ICompletionsPromiseQueueService } from './util/promiseQueue';
export declare enum TelemetryStore {
    Standard = 0,
    Enhanced = 1
}
export declare namespace TelemetryStore {
    function isEnhanced(store: TelemetryStore): boolean;
}
export type TelemetryProperties = {
    [key: string]: string;
};
export type TelemetryMeasurements = {
    [key: string]: number;
};
/**
 * A class holding the data we want send to telemetry,
 * {@link TelemetryData.properties} containing the strings
 * and {@link TelemetryData.measurements} containing the numbers.
 *
 * Additionally, this keeps tracks of timestamps {@link TelemetryData.created} and {@link TelemetryData.displayed}
 * that can be used to track when this object was created or when information
 * contained in this object was surfaced to the user.
 *
 * This is meant be used as an argument to
 * {@link telemetry}, {@link telemetryError}, or {@link telemetryException}.
 */
export declare class TelemetryData {
    properties: TelemetryProperties;
    measurements: TelemetryMeasurements;
    issuedTime: number;
    displayedTime?: number;
    private static keysExemptedFromSanitization;
    protected constructor(properties: TelemetryProperties, measurements: TelemetryMeasurements, issuedTime: number);
    static createAndMarkAsIssued(properties?: TelemetryProperties, measurements?: TelemetryMeasurements): TelemetryData;
    /**
     * @param properties new properties, which will overwrite old ones in case of a clash
     * @param measurements new measurements, which will overwrite old ones in case of a clash
     * @returns a TelemetryData object whose contents extend (copies of) the current one's and whose creation date is not updated
     */
    extendedBy(properties?: TelemetryProperties, measurements?: TelemetryMeasurements): TelemetryData;
    /**
     * registers current time as the point where this was displayed
     * (no-op if a display time is already registered)
     */
    markAsDisplayed(): void;
    /** This function is a fallback - if we are a TelemetryData object instead of a TelemetryWithExp,
     * we don't actually know our real ExP assignment list. Historically, all telemetry has been emitted
     * with a 'partial' list of assignments that are gathered using a blank set of filters, and there may
     * be downstream telemetry users depending on this partial list.
     * However, this partial list likely disagrees with the true, complete list that TelemetryWithExp
     * can emit, so there is the possibility of inconsistent telemetry (different events from the same user/context
     * will have different experimental assignments).
     * All telemetry events that impact scorecards (namely ghostText) MUST use TelemetryWithExp, but
     * this fallback is a bandaid for other events that don't impact scorecards.
     * Downstream users SHOULD NOT depend on the partial list, and this fallback should eventually be removed
     * in favor of properly plumbing a TelemetryWithExp object through in the cases where the
     * assignment list is necessary.
     */
    extendWithExpTelemetry(accessor: ServicesAccessor): Promise<void>;
    extendWithEditorAgnosticFields(accessor: ServicesAccessor): void;
    /**
     * Iterate config keys defined in the package.json, lookup current config
     * value and return as telemetry property. Property name in dotted notation
     * and value is a json string.
     * e.g. { 'copilot.autocompletion.count': 3 }
     */
    extendWithConfigProperties(accessor: ServicesAccessor): void;
    extendWithRequestId(requestId: RequestId): void;
    private static keysToRemoveFromStandardTelemetry;
    /**
     * Remove the known properties relating to repository information from the telemetry data if necessary
     */
    static maybeRemoveRepoInfoFromProperties(store: TelemetryStore, map: {
        [key: string]: string;
    }): {
        [key: string]: string;
    };
    sanitizeKeys(): void;
    multiplexProperties(): void;
    static sanitizeKeys<V>(map?: {
        [key: string]: V;
    }): {
        [key: string]: V;
    };
    static multiplexProperties(properties: TelemetryProperties): TelemetryProperties;
    updateMeasurements(now: number): void;
    makeReadyForSending(accessor: ServicesAccessor, store: TelemetryStore, includeExp: 'IncludeExp' | 'SkipExp', now: number): Promise<void>;
}
/**
 * A TelemetryData object that also contains the filters and ExP config that are applicable to current request context.
 * Telemetry which is used to generate scorecards *must* use this class over the bare TelemetryData class in order
 * to guarantee that the events are attached to the correct scorecard. Known events that fall into this category are:
 * - `ghostText.issued`
 * - `ghostText.shown`
 * - `ghostText.accepted`
 * - `ghostText.performance`
 *
 * It is highly recommended to use this class for most other telemetry events as well, to ensure that the events can be
 * tied correctly to active experiments in post-hoc analyses.
 *
 * This object should only be created directly by the `updateExPValuesAndAssignments` function of `experiments/features.ts`,
 * unless testing.
 *
 * This class should not be used for telemetry that does not take place in the context of a "completion request".
 */
export declare class TelemetryWithExp extends TelemetryData {
    filtersAndExp: {
        filters: FilterSettings;
        exp: ExpConfig;
    };
    constructor(properties: TelemetryProperties, measurements: TelemetryMeasurements, issuedTime: number, filtersAndExp: {
        filters: FilterSettings;
        exp: ExpConfig;
    });
    extendedBy(properties?: TelemetryProperties, measurements?: TelemetryMeasurements): TelemetryWithExp;
    /** Include the known ExP assignment list into the properties/measurements blocks
     * of the telemetry event.
     * This method is correct/consistent for TelemetryWithExp, unlike TelemetryData's.
     */
    extendWithExpTelemetry(): Promise<void>;
    static createEmptyConfigForTesting(): TelemetryWithExp;
}
/**
 * Creates an object containing info about the length of the prompt suitable
 * for saving in standard telemetry.
 */
export declare function telemetrizePromptLength(prompt: Prompt): {
    [key: string]: number;
};
export declare function now(): number;
export declare function telemetry(accessor: ServicesAccessor, name: string, telemetryData?: TelemetryData, store?: TelemetryStore): void;
export declare function telemetryExpProblem(accessor: ServicesAccessor, telemetryProperties: {
    reason: string;
}): void;
/**
 * Send a telemetry message as-is, without the usual Copilot-specific processing from
 * `createAndMarkAsIssued` / `makeReadyForSending`.
 *
 * There is also no sanitization or validation currently. When adding new messages
 * using this method, make sure to add some tests of the fields, e.g. in `extension/src/ghostTest/telemetry.test.ts`.
 */
export declare function telemetryRaw(accessor: ServicesAccessor, name: string, props: TelemetryProperties, measurements: TelemetryMeasurements): void;
export declare function telemetryException(telemetryService: ICompletionsTelemetryService, maybeError: unknown, transaction: string): void;
type TelemetryCatcher = (...args: never[]) => unknown;
export declare function telemetryCatch<F extends TelemetryCatcher>(completionsTelemetryService: ICompletionsTelemetryService, completionsPromiseQueueService: ICompletionsPromiseQueueService, fn: F, transaction: string): (...args: Parameters<F>) => void;
export declare function telemetryError(accessor: ServicesAccessor, name: string, telemetryData?: TelemetryData, store?: TelemetryStore): void;
export declare function logEngineCompletion(accessor: ServicesAccessor, completionText: string, jsonData: APIJsonData, requestId: RequestId, choiceIndex: number): void;
export declare function logEnginePrompt(accessor: ServicesAccessor, prompt: Prompt, telemetryData: TelemetryData): void;
export declare abstract class CopilotTelemetryReporter {
    abstract sendTelemetryEvent(eventName: string, properties?: {
        [key: string]: string;
    }, measurements?: {
        [key: string]: number;
    }): void;
    abstract sendTelemetryErrorEvent(eventName: string, properties?: {
        [key: string]: string;
    }, measurements?: {
        [key: string]: number;
    }, errorProps?: string[]): void;
    abstract dispose(): Promise<void>;
}
export declare const ICompletionsTelemetryReporters: import("../../../../../util/common/services").ServiceIdentifier<ICompletionsTelemetryReporters>;
export interface ICompletionsTelemetryReporters {
    readonly _serviceBrand: undefined;
    getReporter(accessor: ServicesAccessor, store?: TelemetryStore): CopilotTelemetryReporter | undefined;
    getEnhancedReporter(accessor: ServicesAccessor): CopilotTelemetryReporter | undefined;
    getFTReporter(accessor: ServicesAccessor): CopilotTelemetryReporter | undefined;
    setReporter(reporter: CopilotTelemetryReporter): void;
    setEnhancedReporter(reporter: CopilotTelemetryReporter): void;
    setFTReporter(reporter: CopilotTelemetryReporter): void;
    deactivate(): Promise<void>;
}
export declare class TelemetryReporters implements ICompletionsTelemetryReporters {
    _serviceBrand: undefined;
    private reporter;
    private reporterEnhanced;
    private reporterFT;
    getReporter(accessor: ServicesAccessor, store?: TelemetryStore): CopilotTelemetryReporter | undefined;
    getEnhancedReporter(accessor: ServicesAccessor): CopilotTelemetryReporter | undefined;
    getFTReporter(accessor: ServicesAccessor): CopilotTelemetryReporter | undefined;
    setReporter(reporter: CopilotTelemetryReporter): void;
    setEnhancedReporter(reporter: CopilotTelemetryReporter): void;
    setFTReporter(reporter: CopilotTelemetryReporter): void;
    /**
     * Synchronously unassign all reporters and asynchronously shut them down.
     */
    deactivate(): Promise<void>;
}
export {};
//# sourceMappingURL=telemetry.d.ts.map