/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { DiagnosticSeverity, Position } from 'vscode-languageserver-types';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { analyzeQuery, updateSignatureResolver } from './semanticAnalysis';
const previousResolvers = {};
function copySettingSeverity(elements, severity) {
    return elements.map(({ message, startPosition, endPosition }) => ({
        severity: severity,
        message,
        range: {
            start: Position.create(startPosition.line, startPosition.column),
            end: Position.create(endPosition.line, endPosition.column),
        },
        offsets: {
            start: startPosition.offset,
            end: endPosition.offset,
        },
    }));
}
function copySymbolTable(symbolTable) {
    return symbolTable.map(({ variable, definitionPosition, types, references, labels }) => {
        return {
            variable,
            definitionPosition,
            types: Array.from(types),
            references: Array.from(references),
            labels: labelTreeFromJava(labels),
        };
    });
}
function labelTreeFromJava(labels) {
    if ('children' in labels) {
        const children = [];
        for (const c of labels.children) {
            children.push(labelTreeFromJava(c));
        }
        return { andOr: labels.andOr, children };
    }
    else {
        return { value: labels.value, validFrom: labels.validFrom };
    }
}
function updateResolverForVersion(dbSchema, cypherVersion) {
    const previousResolver = previousResolvers?.[cypherVersion];
    const currentResolver = {
        procedures: dbSchema?.procedures?.[cypherVersion],
        functions: dbSchema?.functions?.[cypherVersion],
    };
    if (JSON.stringify(previousResolver) !== JSON.stringify(currentResolver)) {
        previousResolvers[cypherVersion] = currentResolver;
        const procedures = Object.values(dbSchema?.procedures?.[cypherVersion] ?? {});
        const functions = Object.values(dbSchema?.functions?.[cypherVersion] ?? {});
        updateSignatureResolver({
            procedures: procedures,
            functions: functions,
        }, cypherVersion);
    }
}
export function wrappedSemanticAnalysis(query, dbSchema, parsedVersion) {
    try {
        const defaultVersion = dbSchema?.defaultLanguage;
        const cypherVersion = parsedVersion ?? defaultVersion ?? 'CYPHER 5';
        updateResolverForVersion(dbSchema, cypherVersion);
        const semanticErrorsResult = analyzeQuery(query, cypherVersion);
        const errors = semanticErrorsResult.errors;
        const notifications = semanticErrorsResult.notifications;
        const symbolTable = semanticErrorsResult.symbolTable;
        return {
            errors: copySettingSeverity(errors, DiagnosticSeverity.Error),
            notifications: copySettingSeverity(notifications, DiagnosticSeverity.Warning),
            symbolTable: copySymbolTable(symbolTable),
        };
    }
    catch (e) {
        /* Ignores exceptions if they happen calling the semantic analysis. Should not happen but this is just defensive in case it did */
        return { errors: [], notifications: [], symbolTable: [] };
    }
}
//# sourceMappingURL=semanticAnalysisWrapper.js.map