import { readFile } from '../readers/file-reader.js';
import * as JDLReader from '../readers/jdl-reader.js';
import Issues from './issues/issues.js';
import { checkEntities } from './entity-linter.js';
import { checkFields } from './field-linter.js';
import { checkEnums } from './enum-linter.js';
import { checkRelationships } from './relationship-linter.js';
export function createJDLLinterFromContent(jdlString) {
    if (!jdlString) {
        throw new Error('A JDL content must be passed to create a new JDL linter.');
    }
    return makeJDLLinter(jdlString);
}
export function createJDLLinterFromFile(file) {
    if (!file) {
        throw new Error('A JDL file must be passed to create a new JDL linter.');
    }
    const jdlString = readFile(file);
    return makeJDLLinter(jdlString);
}
let cst;
let issues;
function makeJDLLinter(content) {
    cst = JDLReader.getCstFromContent(content);
    issues = new Issues();
    return {
        check: () => {
            checkForEntityDeclarationIssues();
            checkForFieldDeclarationIssues();
            checkForEnumDeclarationIssues();
            checkForRelationshipIssues();
            return issues;
        },
    };
}
function checkForEntityDeclarationIssues() {
    const entityDeclarations = cst.children.entityDeclaration;
    const entityIssues = checkEntities(entityDeclarations);
    issues.addEntityIssues(entityIssues);
}
function checkForFieldDeclarationIssues() {
    const entityDeclarations = cst.children.entityDeclaration;
    if (!entityDeclarations) {
        return;
    }
    entityDeclarations.forEach(entityDeclaration => {
        const entityName = entityDeclaration.children.NAME[0].image;
        const fieldDeclarations = getFieldDeclarationsFromEntity(entityDeclaration);
        if (fieldDeclarations.length !== 0) {
            const fieldIssues = checkFields(entityName, fieldDeclarations);
            issues.addFieldIssues(fieldIssues);
        }
    });
}
function checkForEnumDeclarationIssues() {
    const enumDeclarations = cst.children.enumDeclaration;
    const entityDeclarations = cst.children.entityDeclaration;
    const fieldDeclarations = getAllFieldDeclarations(entityDeclarations);
    const enumIssues = checkEnums(enumDeclarations, fieldDeclarations);
    issues.addEnumIssues(enumIssues);
}
function checkForRelationshipIssues() {
    const relationshipDeclarations = cst.children.relationDeclaration;
    const relationshipIssues = checkRelationships(relationshipDeclarations);
    issues.addRelationshipIssues(relationshipIssues);
}
function getAllFieldDeclarations(entityDeclarations) {
    if (!entityDeclarations) {
        return [];
    }
    return entityDeclarations.reduce((fieldDeclarations, entityDeclaration) => {
        return fieldDeclarations.concat(getFieldDeclarationsFromEntity(entityDeclaration));
    }, []);
}
function getFieldDeclarationsFromEntity(entityDeclaration) {
    const entityBody = entityDeclaration.children.entityBody;
    const entityFields = entityBody && entityBody[0].children.fieldDeclaration;
    if (entityBody && entityFields) {
        return entityFields;
    }
    return [];
}
