"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InlayHintsAdapter = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const typeConvert = tslib_1.__importStar(require("../../../../common/vscode/converter"));
const types = tslib_1.__importStar(require("../../../../common/vscode/ext-types"));
class InlayHintsAdapter {
    constructor(_documents, _provider, _commands) {
        this._documents = _documents;
        this._provider = _provider;
        this._commands = _commands;
        this._cache = new ide_core_common_1.Cache('InlayHints');
        this._disposables = new Map();
    }
    async provideInlayHints(resource, ran, token) {
        const doc = this._documents.getDocument(resource);
        const range = typeConvert.Range.to(ran);
        const hints = await this._provider.provideInlayHints(doc, range, token);
        if (!Array.isArray(hints) || hints.length === 0) {
            // bad result
            // this._logService.trace(`[InlayHints] NO inlay hints from '${this._extension.identifier.value}' for ${ran}`);
            return undefined;
        }
        if (token.isCancellationRequested) {
            // cancelled -> return without further ado, esp no caching
            // of results as they will leak
            return undefined;
        }
        const pid = this._cache.add(hints);
        this._disposables.set(pid, new ide_core_common_1.DisposableStore());
        const result = { hints: [], cacheId: pid };
        for (let i = 0; i < hints.length; i++) {
            if (this._isValidInlayHint(hints[i], range)) {
                result.hints.push(this._convertInlayHint(hints[i], [pid, i]));
            }
        }
        // this._logService.trace(`[InlayHints] ${result.hints.length} inlay hints from '${this._extension.identifier.value}' for ${ran}`);
        return result;
    }
    async resolveInlayHint(id, token) {
        if (typeof this._provider.resolveInlayHint !== 'function') {
            return undefined;
        }
        const item = this._cache.get(...id);
        if (!item) {
            return undefined;
        }
        const hint = await this._provider.resolveInlayHint(item, token);
        if (!hint) {
            return undefined;
        }
        if (!this._isValidInlayHint(hint)) {
            return undefined;
        }
        return this._convertInlayHint(hint, id);
    }
    async releaseHints(id) {
        var _a;
        (_a = this._disposables.get(id)) === null || _a === void 0 ? void 0 : _a.dispose();
        this._disposables.delete(id);
        this._cache.delete(id);
    }
    _isValidInlayHint(hint, range) {
        if (hint.label.length === 0 || (Array.isArray(hint.label) && hint.label.every((part) => part.value.length === 0))) {
            // console.log('INVALID inlay hint, empty label', hint);
            return false;
        }
        if (range && !range.contains(hint.position)) {
            // console.log('INVALID inlay hint, position outside range', range, hint);
            return false;
        }
        return true;
    }
    _convertInlayHint(hint, id) {
        const disposables = this._disposables.get(id[0]);
        if (!disposables) {
            throw Error('DisposableStore is missing...');
        }
        const result = {
            label: '', // fill-in below
            tooltip: typeConvert.MarkdownString.fromStrict(hint.tooltip),
            position: typeConvert.Position.from(hint.position),
            textEdits: hint.textEdits && hint.textEdits.map(typeConvert.TextEdit.from),
            kind: hint.kind && typeConvert.InlayHintKind.from(hint.kind),
            paddingLeft: hint.paddingLeft,
            paddingRight: hint.paddingRight,
            cacheId: id,
        };
        if (typeof hint.label === 'string') {
            result.label = hint.label;
        }
        else {
            result.label = hint.label.map((part) => {
                const result = { label: part.value };
                result.tooltip = typeConvert.MarkdownString.fromStrict(part.tooltip);
                if (types.Location.isLocation(part.location)) {
                    result.location = typeConvert.location.from(part.location);
                }
                if (part.command) {
                    result.command = this._commands.toInternal(part.command, disposables);
                }
                return result;
            });
        }
        return result;
    }
}
exports.InlayHintsAdapter = InlayHintsAdapter;
//# sourceMappingURL=inlay-hints.js.map