"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtHostProgress = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const vscode_1 = require("../../../common/vscode");
const converter_1 = require("../../../common/vscode/converter");
class ExtHostProgress {
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
        this._handles = 0;
        this._mapHandleToCancellationSource = new Map();
        this._proxy = this.rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadProgress);
    }
    withProgress(extension, options, task) {
        const handle = this._handles++;
        const { title, location, cancellable } = options;
        const source = (0, ide_core_common_1.formatLocalize)('extensionSource', '{0} (Extension)', extension.name);
        this._proxy.$startProgress(handle, { location: converter_1.ProgressLocation.from(location), title, source, cancellable }, extension);
        return this._withProgress(handle, task, !!cancellable);
    }
    _withProgress(handle, task, cancellable) {
        let source;
        if (cancellable) {
            source = new ide_core_common_1.CancellationTokenSource();
            this._mapHandleToCancellationSource.set(handle, source);
        }
        const progressEnd = (handle) => {
            this._proxy.$progressEnd(handle);
            this._mapHandleToCancellationSource.delete(handle);
            if (source) {
                source.dispose();
            }
        };
        let p;
        try {
            p = task(new ProgressCallback(this._proxy, handle), cancellable && source ? source.token : ide_core_common_1.CancellationToken.None);
        }
        catch (err) {
            progressEnd(handle);
            throw err;
        }
        p.then((result) => progressEnd(handle), (err) => progressEnd(handle));
        return p;
    }
    $acceptProgressCanceled(handle) {
        const source = this._mapHandleToCancellationSource.get(handle);
        if (source) {
            source.cancel();
            this._mapHandleToCancellationSource.delete(handle);
        }
    }
}
exports.ExtHostProgress = ExtHostProgress;
function mergeProgress(result, currentValue) {
    result.message = currentValue.message;
    if (typeof currentValue.increment === 'number') {
        if (typeof result.increment === 'number') {
            result.increment += currentValue.increment;
        }
        else {
            result.increment = currentValue.increment;
        }
    }
    return result;
}
class ProgressCallback extends ide_core_common_1.Progress {
    constructor(_proxy, _handle) {
        super((p) => this.throttledReport(p));
        this._proxy = _proxy;
        this._handle = _handle;
    }
    throttledReport(p) {
        this._proxy.$progressReport(this._handle, p);
    }
}
tslib_1.__decorate([
    (0, ide_core_common_1.throttle)(100, (result, currentValue) => mergeProgress(result, currentValue), () => Object.create(null)),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Object]),
    tslib_1.__metadata("design:returntype", void 0)
], ProgressCallback.prototype, "throttledReport", null);
//# sourceMappingURL=ext.host.progress.js.map