"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallHierarchyAdapter = void 0;
const tslib_1 = require("tslib");
const id_generator_1 = require("@opensumi/ide-core-common/lib/id-generator");
const Converter = tslib_1.__importStar(require("../../../../common/vscode/converter"));
class CallHierarchyAdapter {
    constructor(documents, provider) {
        this.documents = documents;
        this.provider = provider;
        this._idPool = new id_generator_1.IdGenerator('');
        this._cache = new Map();
    }
    async prepareSession(uri, position, token) {
        const documentData = this.documents.getDocumentData(uri);
        if (!documentData) {
            return Promise.reject(new Error(`There is no document for ${uri}`));
        }
        const doc = documentData.document;
        const pos = Converter.toPosition(position);
        const items = await this.provider.prepareCallHierarchy(doc, pos, token);
        if (!items) {
            return undefined;
        }
        const sessionId = this._idPool.nextId();
        this._cache.set(sessionId, new Map());
        if (Array.isArray(items)) {
            return items.map((item) => this._cacheAndConvertItem(sessionId, item));
        }
        else {
            return [this._cacheAndConvertItem(sessionId, items)];
        }
    }
    async provideCallsTo(sessionId, itemId, token) {
        const item = this._itemFromCache(sessionId, itemId);
        if (!item) {
            throw new Error('missing call hierarchy item');
        }
        const calls = await this.provider.provideCallHierarchyIncomingCalls(item, token);
        if (!calls) {
            return undefined;
        }
        return calls.map((call) => ({
            from: this._cacheAndConvertItem(sessionId, call.from),
            fromRanges: call.fromRanges.map((r) => Converter.fromRange(r)),
        }));
    }
    async provideCallsFrom(sessionId, itemId, token) {
        const item = this._itemFromCache(sessionId, itemId);
        if (!item) {
            throw new Error('missing call hierarchy item');
        }
        const calls = await this.provider.provideCallHierarchyOutgoingCalls(item, token);
        if (!calls) {
            return undefined;
        }
        return calls.map((call) => ({
            to: this._cacheAndConvertItem(sessionId, call.to),
            fromRanges: call.fromRanges.map((r) => Converter.fromRange(r)),
        }));
    }
    releaseSession(sessionId) {
        this._cache.delete(sessionId);
    }
    _cacheAndConvertItem(sessionId, item) {
        var _a;
        const map = this._cache.get(sessionId);
        const dto = {
            _sessionId: sessionId,
            _itemId: map.size.toString(36),
            name: item.name,
            detail: item.detail,
            kind: Converter.SymbolKind.fromSymbolKind(item.kind),
            uri: item.uri,
            range: Converter.fromRange(item.range),
            selectionRange: Converter.fromRange(item.selectionRange),
            tags: (_a = item.tags) === null || _a === void 0 ? void 0 : _a.map(Converter.SymbolTag.from),
        };
        map.set(dto._itemId, item);
        return dto;
    }
    _itemFromCache(sessionId, itemId) {
        const map = this._cache.get(sessionId);
        return map === null || map === void 0 ? void 0 : map.get(itemId);
    }
}
exports.CallHierarchyAdapter = CallHierarchyAdapter;
//# sourceMappingURL=callhierarchy.js.map