import { capitalize } from 'lodash-es';
import { validations } from '../../jhipster/index.js';
import formatComment from '../../utils/format-utils.js';
import { camelCase } from '../../utils/string-utils.js';
import fieldTypes from '../../jhipster/field-types.js';
const { Validations: { UNIQUE, REQUIRED }, } = validations;
const { isBlobType } = fieldTypes;
const { ANY_BLOB, BLOB, IMAGE_BLOB, TEXT_BLOB } = fieldTypes.CommonDBTypes;
const { ANY, IMAGE, TEXT } = fieldTypes.BlobTypes;
const { BYTES } = fieldTypes.RelationalOnlyDBTypes;
export default { convert };
export function convert(jdlObject) {
    if (!jdlObject) {
        throw new Error('A JDL Object must be passed to convert JDL fields to JSON.');
    }
    const convertedFields = new Map();
    jdlObject.forEachEntity(jdlEntity => {
        const convertedEntityFields = getConvertedFieldsForEntity(jdlEntity, jdlObject);
        convertedFields.set(jdlEntity.name, convertedEntityFields);
    });
    return convertedFields;
}
function getConvertedFieldsForEntity(jdlEntity, jdlObject) {
    const convertedEntityFields = [];
    jdlEntity.forEachField((jdlField) => {
        let fieldData = {
            fieldName: camelCase(jdlField.name),
            fieldType: jdlField.type,
        };
        const comment = formatComment(jdlField.comment);
        if (comment) {
            fieldData.documentation = comment;
        }
        if (jdlObject.hasEnum(jdlField.type)) {
            fieldData.fieldValues = jdlObject.getEnum(fieldData.fieldType)?.getValuesAsString();
            const fieldTypeComment = jdlObject.getEnum(fieldData.fieldType)?.comment;
            if (fieldTypeComment) {
                fieldData.fieldTypeDocumentation = fieldTypeComment;
            }
            const fieldValuesJavadocs = jdlObject.getEnum(fieldData.fieldType)?.getValueJavadocs();
            if (fieldValuesJavadocs && Object.keys(fieldValuesJavadocs).length > 0) {
                fieldData.fieldValuesJavadocs = fieldValuesJavadocs;
            }
        }
        if (fieldData.fieldType && isBlobType(fieldData.fieldType)) {
            const blobFieldData = getBlobFieldData(fieldData.fieldType);
            fieldData = {
                ...fieldData,
                ...blobFieldData,
            };
        }
        if (jdlField.validationQuantity() !== 0) {
            const fieldValidations = getFieldValidations(jdlField);
            fieldData = {
                ...fieldData,
                ...fieldValidations,
            };
        }
        if (jdlField.optionQuantity() !== 0) {
            const fieldOptions = getOptionsForField(jdlField);
            fieldData = {
                ...fieldData,
                ...fieldOptions,
            };
        }
        convertedEntityFields.push(fieldData);
    });
    return convertedEntityFields;
}
function getBlobFieldData(fieldType) {
    const blobFieldData = {
        fieldType: BYTES,
    };
    switch (fieldType) {
        case IMAGE_BLOB:
            blobFieldData.fieldTypeBlobContent = IMAGE;
            break;
        case BLOB:
        case ANY_BLOB:
            blobFieldData.fieldTypeBlobContent = ANY;
            break;
        case TEXT_BLOB:
            blobFieldData.fieldTypeBlobContent = TEXT;
            break;
        default:
            throw new Error(`Unrecognised Blob type: ${fieldType}.`);
    }
    return blobFieldData;
}
function getFieldValidations(jdlField) {
    const fieldValidations = {
        fieldValidateRules: [],
    };
    jdlField.forEachValidation(validation => {
        fieldValidations.fieldValidateRules.push(validation.name);
        if (validation.name !== REQUIRED && validation.name !== UNIQUE) {
            fieldValidations[`fieldValidateRules${capitalize(validation.name)}`] = validation.value;
        }
    });
    return fieldValidations;
}
function getOptionsForField(jdlField) {
    const fieldOptions = {
        options: {},
    };
    fieldOptions.options = {};
    jdlField.forEachOption(([key, value]) => {
        fieldOptions.options[key] = value;
    });
    return fieldOptions;
}
