"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initialize = initialize;
const node_1 = require("@volar/language-server/node");
const language_core_1 = require("@vue/language-core");
const language_service_1 = require("@vue/language-service");
function initialize(server, params, ts, tsLocalized) {
    const watchingExtensions = new Set();
    let fileWatcher;
    return server.initialize(params, (0, node_1.createTypeScriptProject)(ts, tsLocalized, async ({ configFileName, sys, uriConverter }) => {
        let compilerOptions;
        let vueCompilerOptions;
        if (configFileName) {
            let commandLine = (0, language_core_1.createParsedCommandLine)(ts, sys, configFileName, true);
            let sysVersion = sys.version;
            let newSysVersion = await sys.sync();
            while (sysVersion !== newSysVersion) {
                commandLine = (0, language_core_1.createParsedCommandLine)(ts, sys, configFileName, true);
                sysVersion = newSysVersion;
                newSysVersion = await sys.sync();
            }
            compilerOptions = commandLine.options;
            vueCompilerOptions = commandLine.vueOptions;
        }
        else {
            compilerOptions = ts.getDefaultCompilerOptions();
            vueCompilerOptions = (0, language_core_1.getDefaultCompilerOptions)();
        }
        vueCompilerOptions.__test = params.initializationOptions.typescript.disableAutoImportCache;
        updateFileWatcher(vueCompilerOptions);
        return {
            languagePlugins: [
                (0, language_core_1.createVueLanguagePlugin)(ts, compilerOptions, vueCompilerOptions, s => uriConverter.asFileName(s)),
            ],
            setup({ project }) {
                project.vue = { compilerOptions: vueCompilerOptions };
                if (project.typescript) {
                    const directoryExists = project.typescript.languageServiceHost.directoryExists?.bind(project.typescript.languageServiceHost);
                    const fileExists = project.typescript.languageServiceHost.fileExists.bind(project.typescript.languageServiceHost);
                    const getScriptSnapshot = project.typescript.languageServiceHost.getScriptSnapshot.bind(project.typescript.languageServiceHost);
                    const globalTypesName = (0, language_core_1.getGlobalTypesFileName)(vueCompilerOptions);
                    const globalTypesContents = `// @ts-nocheck\nexport {};\n` + (0, language_core_1.generateGlobalTypes)(vueCompilerOptions);
                    const globalTypesSnapshot = {
                        getText: (start, end) => globalTypesContents.slice(start, end),
                        getLength: () => globalTypesContents.length,
                        getChangeRange: () => undefined,
                    };
                    if (directoryExists) {
                        project.typescript.languageServiceHost.directoryExists = path => {
                            if (path.endsWith('.vue-global-types')) {
                                return true;
                            }
                            return directoryExists(path);
                        };
                    }
                    project.typescript.languageServiceHost.fileExists = path => {
                        if (path.endsWith(`.vue-global-types/${globalTypesName}`) || path.endsWith(`.vue-global-types\\${globalTypesName}`)) {
                            return true;
                        }
                        return fileExists(path);
                    };
                    project.typescript.languageServiceHost.getScriptSnapshot = path => {
                        if (path.endsWith(`.vue-global-types/${globalTypesName}`) || path.endsWith(`.vue-global-types\\${globalTypesName}`)) {
                            return globalTypesSnapshot;
                        }
                        return getScriptSnapshot(path);
                    };
                }
            },
        };
    }), (0, language_service_1.getFullLanguageServicePlugins)(ts, { disableAutoImportCache: params.initializationOptions.typescript.disableAutoImportCache }));
    function updateFileWatcher(vueCompilerOptions) {
        const extensions = [
            'js', 'cjs', 'mjs', 'ts', 'cts', 'mts', 'jsx', 'tsx', 'json',
            ...(0, language_core_1.getAllExtensions)(vueCompilerOptions).map(ext => ext.slice(1)),
        ];
        const newExtensions = extensions.filter(ext => !watchingExtensions.has(ext));
        if (newExtensions.length) {
            for (const ext of newExtensions) {
                watchingExtensions.add(ext);
            }
            fileWatcher?.then(dispose => dispose.dispose());
            fileWatcher = server.fileWatcher.watchFiles(['**/*.{' + [...watchingExtensions].join(',') + '}']);
        }
    }
}
//# sourceMappingURL=initialize.js.map