"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const node_1 = require("vscode-languageserver/node");
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
const language_support_1 = require("@neo4j-cypher/language-support");
const query_tools_1 = require("@neo4j-cypher/query-tools");
const autocompletion_1 = require("./autocompletion");
const formatting_1 = require("./formatting");
const linting_1 = require("./linting");
const signatureHelp_1 = require("./signatureHelp");
const syntaxColouring_1 = require("./syntaxColouring");
if (process.env.CYPHER_25 === 'true') {
    language_support_1._internalFeatureFlags.cypher25 = true;
}
const connection = (0, node_1.createConnection)(node_1.ProposedFeatures.all);
let settings = undefined;
// Create a simple text document manager.
const documents = new node_1.TextDocuments(vscode_languageserver_textdocument_1.TextDocument);
const neo4jSchemaPoller = new query_tools_1.Neo4jSchemaPoller();
async function lintSingleDocument(document) {
    if (settings?.features?.linting) {
        return (0, linting_1.lintDocument)(document, (diagnostics) => {
            void connection.sendDiagnostics({
                uri: document.uri,
                diagnostics,
            });
        }, neo4jSchemaPoller);
    }
    else {
        void connection.sendDiagnostics({
            uri: document.uri,
            diagnostics: [],
        });
    }
}
function relintAllDocuments() {
    void documents.all().map(lintSingleDocument);
}
connection.onInitialize(() => {
    const result = {
        capabilities: {
            textDocumentSync: node_1.TextDocumentSyncKind.Full,
            // Tell the client what features does the server support
            completionProvider: {
                resolveProvider: false,
                triggerCharacters: ['.', ':', '{', '$', ')', ' '],
            },
            semanticTokensProvider: {
                documentSelector: [{ language: 'cypher' }],
                legend: language_support_1.syntaxColouringLegend,
                range: false,
                full: {
                    delta: false,
                },
            },
            signatureHelpProvider: {
                triggerCharacters: ['(', ',', ')'],
            },
            documentFormattingProvider: true,
        },
    };
    return result;
});
connection.onInitialized(() => {
    void connection.client.register(node_1.DidChangeConfigurationNotification.type, {
        section: 'neo4j',
    });
    const registrationOptions = {
        documentSelector: [{ language: 'cypher' }],
        legend: language_support_1.syntaxColouringLegend,
        range: false,
        full: {
            delta: false,
        },
    };
    void connection.client.register(node_1.SemanticTokensRegistrationType.type, registrationOptions);
});
connection.onDidChangeConfiguration((params) => {
    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
    settings = params.settings?.neo4j;
    relintAllDocuments();
});
documents.onDidChangeContent((change) => lintSingleDocument(change.document));
// Trigger the syntax colouring
connection.languages.semanticTokens.on((0, syntaxColouring_1.applySyntaxColouringForDocument)(documents));
// Trigger the signature help, providing info about functions / procedures
connection.onSignatureHelp((0, signatureHelp_1.doSignatureHelp)(documents, neo4jSchemaPoller));
// Trigger the auto completion
connection.onCompletion((0, autocompletion_1.doAutoCompletion)(documents, neo4jSchemaPoller));
connection.onNotification('connectionUpdated', (connectionSettings) => {
    changeConnection(connectionSettings);
    neo4jSchemaPoller.events.once('schemaFetched', relintAllDocuments);
});
connection.onNotification('updateParameters', (parameters) => {
    neo4jSchemaPoller.setParameters(parameters);
    relintAllDocuments();
});
connection.onDocumentFormatting((params) => {
    return (0, formatting_1.formatDocument)(params, documents);
});
connection.onNotification('connectionDisconnected', () => {
    disconnect();
    relintAllDocuments();
});
documents.listen(connection);
connection.listen();
connection.onExit(() => {
    (0, linting_1.cleanupWorkers)();
});
const changeConnection = (connectionSettings) => {
    disconnect();
    if (neo4jSchemaPoller.connection === undefined &&
        connectionSettings.connect &&
        connectionSettings.password &&
        connectionSettings.connectURL &&
        connectionSettings.user) {
        void neo4jSchemaPoller.persistentConnect(connectionSettings.connectURL, {
            username: connectionSettings.user,
            password: connectionSettings.password,
        }, { appName: 'cypher-language-server' }, connectionSettings.database);
    }
};
const disconnect = () => {
    neo4jSchemaPoller.disconnect();
};
//# sourceMappingURL=server.js.map