"use strict";
/* --------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 * ------------------------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProgressPart = void 0;
const vscode_1 = require("vscode");
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
const Is = require("./utils/is");
class ProgressPart {
    constructor(_client, _token, done) {
        this._client = _client;
        this._token = _token;
        this._reported = 0;
        this._disposable = this._client.onProgress(vscode_languageserver_protocol_1.WorkDoneProgress.type, this._token, (value) => {
            switch (value.kind) {
                case 'begin':
                    this.begin(value);
                    break;
                case 'report':
                    this.report(value);
                    break;
                case 'end':
                    this.done();
                    done && done(this);
                    break;
            }
        });
    }
    begin(params) {
        // Since we don't use commands this will be a silent window progress with a hidden notification.
        vscode_1.window.withProgress({ location: vscode_1.ProgressLocation.Window, cancellable: params.cancellable, title: params.title }, async (progress, cancellationToken) => {
            this._progress = progress;
            this._infinite = params.percentage === undefined;
            this._cancellationToken = cancellationToken;
            this._cancellationToken.onCancellationRequested(() => {
                this._client.sendNotification(vscode_languageserver_protocol_1.WorkDoneProgressCancelNotification.type, { token: this._token });
            });
            this.report(params);
            return new Promise((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            });
        });
    }
    report(params) {
        if (this._infinite && Is.string(params.message)) {
            this._progress.report({ message: params.message });
        }
        else if (Is.number(params.percentage)) {
            let percentage = Math.max(0, Math.min(params.percentage, 100));
            let delta = Math.max(0, percentage - this._reported);
            this._progress.report({ message: params.message, increment: delta });
            this._reported += delta;
        }
    }
    cancel() {
        if (this._disposable) {
            this._disposable.dispose();
            this._disposable = undefined;
        }
        if (this._reject) {
            this._reject();
            this._resolve = undefined;
            this._reject = undefined;
        }
    }
    done() {
        if (this._disposable) {
            this._disposable.dispose();
            this._disposable = undefined;
        }
        if (this._resolve) {
            this._resolve();
            this._resolve = undefined;
            this._reject = undefined;
        }
    }
}
exports.ProgressPart = ProgressPart;
//# sourceMappingURL=progressPart.js.map