import BasicEntityConverter from './jdl-to-json-basic-entity-converter.js';
import FieldConverter from './jdl-to-json-field-converter.js';
import RelationshipConverter from './jdl-to-json-relationship-converter.js';
import AigcConverter from './jdl-to-json-aigc-converter.js';
import OptionConverter from './jdl-to-json-option-converter.js';
let entities;
let jdlObject;
let entitiesPerApplication;
export default { convert };
export function convert(args) {
    if (!args?.jdlObject) {
        throw new Error('The JDL object is mandatory.');
    }
    init(args);
    setEntitiesPerApplication();
    if (entitiesPerApplication.size === 0 && jdlObject) {
        const applicationNames = jdlObject.getApplications().map(jdlApplication => jdlApplication.getConfigurationOptionValue('baseName'));
        return new Map(applicationNames.map(applicationName => [applicationName, []]));
    }
    setBasicEntityInformation();
    setFields();
    setRelationships();
    setAigcs();
    setApplicationToEntities();
    const entitiesForEachApplication = getEntitiesForEachApplicationMap();
    setOptions(entitiesForEachApplication);
    formatEntitiesForEachApplication(entitiesForEachApplication);
    addApplicationsWithoutEntities(entitiesForEachApplication);
    return entitiesForEachApplication;
}
function init(args) {
    if (jdlObject) {
        resetState();
    }
    jdlObject = args.jdlObject;
    entities = {};
    entitiesPerApplication = new Map();
}
function resetState() {
    jdlObject = null;
    entities = null;
}
function setEntitiesPerApplication() {
    jdlObject?.forEachApplication((jdlApplication) => {
        const entityNames = jdlApplication.getEntityNames();
        if (entityNames.length === 0) {
            return;
        }
        const baseName = jdlApplication.getConfigurationOptionValue('baseName');
        entitiesPerApplication.set(baseName, entityNames);
    });
}
function setBasicEntityInformation() {
    const convertedEntities = BasicEntityConverter.convert(jdlObject.getEntities());
    convertedEntities.forEach((jsonEntity, entityName) => {
        entities[entityName] = jsonEntity;
    });
}
function setFields() {
    const convertedFields = FieldConverter.convert(jdlObject);
    convertedFields.forEach((entityFields, entityName) => {
        entities[entityName].addFields(entityFields);
    });
}
function setRelationships() {
    const convertedRelationships = RelationshipConverter.convert(jdlObject?.getRelationships(), jdlObject?.getEntityNames());
    convertedRelationships.forEach((entityRelationships, entityName) => {
        entities[entityName].addRelationships(entityRelationships);
    });
}
function setAigcs() {
    const convertedAigs = AigcConverter.convert(jdlObject.getAigcs(), jdlObject.getEntityNames());
    convertedAigs.forEach((aigcs, entityName) => {
        entities[entityName].addAigc(aigcs);
    });
}
function setApplicationToEntities() {
    jdlObject?.forEachApplication((jdlApplication) => {
        const baseName = jdlApplication.getConfigurationOptionValue('baseName');
        jdlApplication.forEachEntityName((entityName) => {
            if (!entities[entityName]) {
                return;
            }
            entities[entityName].applications.push(baseName);
        });
    });
}
function setOptions(entitiesForEachApplication) {
    const convertedOptionContents = OptionConverter.convert(jdlObject);
    convertedOptionContents.forEach((optionContent, entityName) => {
        if (!entities[entityName]) {
            console.log('---entityName---', entityName);
        }
        entities[entityName].setOptions(optionContent);
    });
    jdlObject?.forEachApplication(jdlApplication => {
        const convertedOptionContentsForApplication = OptionConverter.convert(jdlApplication);
        const applicationName = jdlApplication.getConfigurationOptionValue('baseName');
        const applicationEntities = entitiesForEachApplication.get(applicationName);
        convertedOptionContentsForApplication.forEach((optionContent, entityName) => {
            if (!applicationEntities[entityName]) {
                return;
            }
            applicationEntities[entityName].setOptions(optionContent);
        });
    });
}
function getEntitiesForEachApplicationMap() {
    const entitiesForEachApplication = new Map();
    entitiesPerApplication.forEach((entityNames, applicationName) => {
        const entitiesInObject = entityNames
            .filter(entityName => !!entities[entityName])
            .map(entityName => entities[entityName])
            .reduce((accumulator, currentEntity) => {
            return {
                ...accumulator,
                [currentEntity.name]: currentEntity,
            };
        }, {});
        entitiesForEachApplication.set(applicationName, entitiesInObject);
    });
    return entitiesForEachApplication;
}
function formatEntitiesForEachApplication(entitiesForEachApplication) {
    entitiesForEachApplication.forEach((applicationEntities, applicationName) => {
        entitiesForEachApplication.set(applicationName, Object.values(applicationEntities));
    });
}
function addApplicationsWithoutEntities(entitiesForEachApplication) {
    jdlObject?.forEachApplication(jdlApplication => {
        if (jdlApplication.getEntityNames().length === 0) {
            entitiesForEachApplication.set(jdlApplication.getConfigurationOptionValue('baseName'), []);
        }
    });
}
