"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainThreadDecorations = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_connection_1 = require("@opensumi/ide-connection");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const ide_decoration_1 = require("@opensumi/ide-decoration");
const vscode_1 = require("../../../common/vscode");
class DecorationRequestsQueue {
    constructor(_proxy) {
        this._proxy = _proxy;
        this._idPool = 0;
        this._requests = Object.create(null);
        this._resolver = Object.create(null);
        //
    }
    enqueue(handle, uri, token) {
        const id = ++this._idPool;
        const result = new Promise((resolve) => {
            this._requests[id] = { id, handle, uri };
            this._resolver[id] = resolve;
            this._processQueue();
        });
        token.onCancellationRequested(() => {
            delete this._requests[id];
            delete this._resolver[id];
        });
        return result;
    }
    _processQueue() {
        if (typeof this._timer === 'number') {
            // already queued
            return;
        }
        this._timer = setTimeout(() => {
            // make request
            const requests = this._requests;
            const resolver = this._resolver;
            this._proxy.$provideFileDecorations(Object.values(requests), ide_core_common_1.CancellationToken.None).then((data) => {
                // eslint-disable-next-line guard-for-in
                for (const id in resolver) {
                    resolver[id](data[id]);
                }
            });
            // reset
            this._requests = [];
            this._resolver = [];
            this._timer = undefined;
        }, 0);
    }
}
let MainThreadDecorations = class MainThreadDecorations {
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
        this._provider = new Map();
        this.proxy = this.rpcProtocol.getProxy(vscode_1.ExtHostAPIIdentifier.ExtHostDecorations);
        this._requestQueue = new DecorationRequestsQueue(this.proxy);
    }
    dispose() {
        this._provider.forEach((value) => (0, ide_core_common_1.dispose)(value));
        this._provider.clear();
    }
    $registerDecorationProvider(handle, label) {
        const emitter = new ide_core_common_1.Emitter();
        const registration = this.decorationsService.registerDecorationsProvider({
            label,
            onDidChange: emitter.event,
            provideDecorations: (uri, token) => this._requestQueue.enqueue(handle, uri, token).then((data) => {
                if (!data) {
                    return undefined;
                }
                const [propagate, tooltip, badge, themeColor] = data;
                return {
                    weight: 10 /* 向下兼容 */,
                    bubble: propagate || false,
                    color: themeColor === null || themeColor === void 0 ? void 0 : themeColor.id,
                    tooltip,
                    letter: badge,
                };
            }),
        });
        this._provider.set(handle, [emitter, registration]);
    }
    $onDidChange(handle, resources) {
        const provider = this._provider.get(handle);
        if (provider) {
            const [emitter] = provider;
            emitter.fire(resources && resources.map((r) => ide_core_common_1.Uri.revive(r)));
        }
    }
    $unregisterDecorationProvider(handle) {
        const provider = this._provider.get(handle);
        if (provider) {
            (0, ide_core_common_1.dispose)(provider);
            this._provider.delete(handle);
        }
    }
};
exports.MainThreadDecorations = MainThreadDecorations;
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_decoration_1.IDecorationsService),
    tslib_1.__metadata("design:type", ide_decoration_1.IDecorationsService)
], MainThreadDecorations.prototype, "decorationsService", void 0);
exports.MainThreadDecorations = MainThreadDecorations = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__param(0, (0, di_1.Optional)(ide_connection_1.IRPCProtocol)),
    tslib_1.__metadata("design:paramtypes", [Object])
], MainThreadDecorations);
//# sourceMappingURL=main.thread.decoration.js.map