
import { __decorate, __param } from '../../../../../../external/tslib/tslib.es6.js';
import { WindowIntervalTimer } from '../../../base/browser/dom.js';
import { BugIndicatingError } from '../../../base/common/errors.js';
import { Emitter } from '../../../base/common/event.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { localize, localize2 } from '../../../nls.js';
import { Action2 } from '../../../platform/actions/common/actions.js';
import { RawContextKey, ContextKeyExpr } from '../../../platform/contextkey/common/contextkey.js';
import { IContextKeyService } from '../../../platform/contextkey/common/contextkey.service.js';
import '../../../platform/instantiation/common/extensions.js';
import { IQuickInputService } from '../../../platform/quickinput/common/quickInput.service.js';
import { StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js';
import { IStorageService } from '../../../platform/storage/common/storage.service.js';
import { ITelemetryService } from '../../../platform/telemetry/common/telemetry.service.js';
import { IInlineCompletionsService } from './inlineCompletionsService.service.js';

var InlineCompletionsService_1;
const InlineCompletionsSnoozing = ( new RawContextKey('inlineCompletions.snoozed', false, ( localize(147, "Whether inline completions are currently snoozed"))));
let InlineCompletionsService = class InlineCompletionsService extends Disposable {
    static { InlineCompletionsService_1 = this; }
    static { this.SNOOZE_DURATION = 300_000; }
    get snoozeTimeLeft() {
        if (this._snoozeTimeEnd === undefined) {
            return 0;
        }
        return Math.max(0, this._snoozeTimeEnd - Date.now());
    }
    constructor(_contextKeyService, _telemetryService) {
        super();
        this._contextKeyService = _contextKeyService;
        this._telemetryService = _telemetryService;
        this._onDidChangeIsSnoozing = this._register(( new Emitter()));
        this.onDidChangeIsSnoozing = this._onDidChangeIsSnoozing.event;
        this._snoozeTimeEnd = undefined;
        this._recentCompletionIds = [];
        this._timer = this._register(( new WindowIntervalTimer()));
        const inlineCompletionsSnoozing = InlineCompletionsSnoozing.bindTo(this._contextKeyService);
        this._register(this.onDidChangeIsSnoozing(() => inlineCompletionsSnoozing.set(this.isSnoozing())));
    }
    snooze(durationMs = InlineCompletionsService_1.SNOOZE_DURATION) {
        this.setSnoozeDuration(durationMs + this.snoozeTimeLeft);
    }
    setSnoozeDuration(durationMs) {
        if (durationMs < 0) {
            throw ( new BugIndicatingError(`Invalid snooze duration: ${durationMs}. Duration must be non-negative.`));
        }
        if (durationMs === 0) {
            this.cancelSnooze();
            return;
        }
        const wasSnoozing = this.isSnoozing();
        const timeLeft = this.snoozeTimeLeft;
        this._snoozeTimeEnd = Date.now() + durationMs;
        if (!wasSnoozing) {
            this._onDidChangeIsSnoozing.fire(true);
        }
        this._timer.cancelAndSet(() => {
            if (!this.isSnoozing()) {
                this._onDidChangeIsSnoozing.fire(false);
            }
            else {
                throw ( new BugIndicatingError('Snooze timer did not fire as expected'));
            }
        }, this.snoozeTimeLeft + 1);
        this._reportSnooze(durationMs - timeLeft, durationMs);
    }
    isSnoozing() {
        return this.snoozeTimeLeft > 0;
    }
    cancelSnooze() {
        if (this.isSnoozing()) {
            this._reportSnooze(-this.snoozeTimeLeft, 0);
            this._snoozeTimeEnd = undefined;
            this._timer.cancel();
            this._onDidChangeIsSnoozing.fire(false);
        }
    }
    reportNewCompletion(requestUuid) {
        this._lastCompletionId = requestUuid;
        this._recentCompletionIds.unshift(requestUuid);
        if (this._recentCompletionIds.length > 5) {
            this._recentCompletionIds.pop();
        }
    }
    _reportSnooze(deltaMs, totalMs) {
        const deltaSeconds = Math.round(deltaMs / 1000);
        const totalSeconds = Math.round(totalMs / 1000);
        this._telemetryService.publicLog2('inlineCompletions.snooze', {
            deltaSeconds,
            totalSeconds,
            lastCompletionId: this._lastCompletionId,
            recentCompletionIds: this._recentCompletionIds,
        });
    }
};
InlineCompletionsService = InlineCompletionsService_1 = ( __decorate([
    ( __param(0, IContextKeyService)),
    ( __param(1, ITelemetryService))
], InlineCompletionsService));
const snoozeInlineSuggestId = 'editor.action.inlineSuggest.snooze';
const cancelSnoozeInlineSuggestId = 'editor.action.inlineSuggest.cancelSnooze';
const LAST_SNOOZE_DURATION_KEY = 'inlineCompletions.lastSnoozeDuration';
class SnoozeInlineCompletion extends Action2 {
    static { this.ID = snoozeInlineSuggestId; }
    constructor() {
        super({
            id: SnoozeInlineCompletion.ID,
            title: ( localize2(148, "Snooze Inline Suggestions")),
            precondition: ContextKeyExpr.true(),
            f1: true,
        });
    }
    async run(accessor, ...args) {
        const quickInputService = accessor.get(IQuickInputService);
        const inlineCompletionsService = accessor.get(IInlineCompletionsService);
        const storageService = accessor.get(IStorageService);
        let durationMinutes;
        if (args.length > 0 && typeof args[0] === 'number') {
            durationMinutes = args[0];
        }
        if (!durationMinutes) {
            durationMinutes = await this.getDurationFromUser(quickInputService, storageService);
        }
        if (durationMinutes) {
            inlineCompletionsService.setSnoozeDuration(durationMinutes);
        }
    }
    async getDurationFromUser(quickInputService, storageService) {
        const lastSelectedDuration = storageService.getNumber(LAST_SNOOZE_DURATION_KEY, StorageScope.PROFILE, 300_000);
        const items = [
            { label: '1 minute', id: '1', value: 60_000 },
            { label: '5 minutes', id: '5', value: 300_000 },
            { label: '10 minutes', id: '10', value: 600_000 },
            { label: '15 minutes', id: '15', value: 900_000 },
            { label: '30 minutes', id: '30', value: 1_800_000 },
            { label: '60 minutes', id: '60', value: 3_600_000 }
        ];
        const picked = await quickInputService.pick(items, {
            placeHolder: ( localize(149, "Select snooze duration for Code completions and NES")),
            activeItem: items.find(item => item.value === lastSelectedDuration),
        });
        if (picked) {
            storageService.store(LAST_SNOOZE_DURATION_KEY, picked.value, StorageScope.PROFILE, StorageTarget.USER);
            return picked.value;
        }
        return undefined;
    }
}
class CancelSnoozeInlineCompletion extends Action2 {
    static { this.ID = cancelSnoozeInlineSuggestId; }
    constructor() {
        super({
            id: CancelSnoozeInlineCompletion.ID,
            title: ( localize2(150, "Cancel Snooze Inline Suggestions")),
            precondition: InlineCompletionsSnoozing,
            f1: true,
        });
    }
    async run(accessor) {
        accessor.get(IInlineCompletionsService).cancelSnooze();
    }
}

export { CancelSnoozeInlineCompletion, InlineCompletionsService, SnoozeInlineCompletion };
