"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPatched = isPatched;
exports.decorateLanguageService = decorateLanguageService;
const utils_1 = require("../utils");
const call_hierarchy_1 = require("./call-hierarchy");
const completions_1 = require("./completions");
const definition_1 = require("./definition");
const diagnostics_1 = require("./diagnostics");
const find_references_1 = require("./find-references");
const hover_1 = require("./hover");
const implementation_1 = require("./implementation");
const inlay_hints_1 = require("./inlay-hints");
const rename_1 = require("./rename");
const update_imports_1 = require("./update-imports");
const host_1 = require("./host");
const navigate_to_items_1 = require("./navigate-to-items");
const file_references_1 = require("./file-references");
const move_to_file_1 = require("./move-to-file");
const code_action_1 = require("./code-action");
const patchedProject = new Set();
function isPatched(project) {
    return patchedProject.has(project.getProjectName());
}
function decorateLanguageService(ls, snapshotManager, logger, configManager, info, typescript, onDispose) {
    patchedProject.add(info.project.getProjectName());
    // Decorate using a proxy so we can dynamically enable/disable method
    // patches depending on the enabled state of our config
    const proxy = new Proxy(ls, createProxyHandler(configManager));
    (0, host_1.decorateLanguageServiceHost)(info.languageServiceHost);
    decorateLanguageServiceInner(proxy, snapshotManager, logger, info, typescript, onDispose);
    return proxy;
}
function decorateLanguageServiceInner(ls, snapshotManager, logger, info, typescript, onDispose) {
    patchLineColumnOffset(ls, snapshotManager);
    (0, rename_1.decorateRename)(ls, snapshotManager, logger);
    (0, diagnostics_1.decorateDiagnostics)(ls, info, typescript, logger);
    (0, find_references_1.decorateFindReferences)(ls, snapshotManager, logger);
    (0, completions_1.decorateCompletions)(ls, info, typescript, logger);
    (0, definition_1.decorateGetDefinition)(ls, info, typescript, snapshotManager, logger);
    (0, implementation_1.decorateGetImplementation)(ls, snapshotManager, logger);
    (0, update_imports_1.decorateUpdateImports)(ls, snapshotManager, logger);
    (0, call_hierarchy_1.decorateCallHierarchy)(ls, snapshotManager, typescript);
    (0, hover_1.decorateHover)(ls, info, typescript, logger);
    (0, inlay_hints_1.decorateInlayHints)(ls, info, typescript, logger);
    (0, navigate_to_items_1.decorateNavigateToItems)(ls, snapshotManager);
    (0, file_references_1.decorateFileReferences)(ls, snapshotManager);
    (0, move_to_file_1.decorateMoveToRefactoringFileSuggestions)(ls);
    (0, code_action_1.decorateQuickFixAndRefactor)(ls, typescript, snapshotManager);
    decorateDispose(ls, info.project, onDispose);
    return ls;
}
function createProxyHandler(configManager) {
    const decorated = {};
    return {
        get(target, p) {
            // always check for decorated dispose
            if (!configManager.getConfig().enable && p !== 'dispose') {
                return target[p];
            }
            return (decorated[p] ?? target[p]);
        },
        set(_, p, value) {
            decorated[p] = value;
            return true;
        }
    };
}
function patchLineColumnOffset(ls, snapshotManager) {
    if (!ls.toLineColumnOffset) {
        return;
    }
    // We need to patch this because (according to source, only) getDefinition uses this
    const toLineColumnOffset = ls.toLineColumnOffset;
    ls.toLineColumnOffset = (fileName, position) => {
        if ((0, utils_1.isSvelteFilePath)(fileName)) {
            const snapshot = snapshotManager.get(fileName);
            if (snapshot) {
                return snapshot.positionAt(position);
            }
        }
        return toLineColumnOffset(fileName, position);
    };
}
function decorateDispose(ls, project, onDispose) {
    const dispose = ls.dispose;
    ls.dispose = () => {
        patchedProject.delete(project.getProjectName());
        onDispose();
        dispose();
    };
    return ls;
}
//# sourceMappingURL=index.js.map