/**
 * Copyright 2013-2026 the original author or authors from the JHipster project.
 *
 * This file is part of the JHipster project, see https://www.jhipster.tech/
 * for more information.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { kebabCase, lowerFirst, snakeCase, startCase, upperFirst } from 'lodash-es';
import { BlobTypes, fieldTypesValues } from "../../lib/jhipster/field-types.js";
import { validationTypes } from "../../lib/jhipster/index.js";
import { buildMutateDataForProperty } from "../../lib/utils/derived-property.js";
import { pluralize } from "../../lib/utils/string-utils.js";
import { formatDocAsApiDescription } from "../java/support/doc.js";
import { isFieldEnumType } from "./internal/types/field-types.js";
const mutateProperty = {
    propertyNameCapitalized: ({ propertyName }) => upperFirst(propertyName),
    propertyNameUpperSnakeCase: ({ propertyName }) => snakeCase(propertyName).toUpperCase(),
};
export const mutateField = {
    __override__: false,
    fieldIsEnum: data => isFieldEnumType(data),
    ...buildMutateDataForProperty('fieldType', Object.values(fieldTypesValues), { anyData: true }),
    fieldTypeBytes: ({ fieldTypeByte }) => fieldTypeByte,
    ...buildMutateDataForProperty('fieldTypeBlobContent', Object.values(BlobTypes), { prefix: 'blobContentType' }),
    path: ({ fieldName }) => [fieldName],
    propertyName: ({ fieldName }) => fieldName,
    ...mutateProperty,
    fieldApiDescription: ({ documentation }) => (documentation ? formatDocAsApiDescription(documentation) : undefined),
    propertyApiDescription: ({ fieldApiDescription }) => fieldApiDescription,
    fieldNameCapitalized: ({ fieldName }) => upperFirst(fieldName),
    fieldNameUnderscored: ({ fieldName }) => snakeCase(fieldName),
    fieldNameHumanized: ({ fieldName }) => startCase(fieldName),
    ...buildMutateDataForProperty('fieldValidateRules', Object.values(validationTypes), {
        prefix: 'fieldValidation',
        array: true,
        valCheck: (data, value) => data.fieldValidateRules?.includes(value) ?? false,
    }),
    fieldValidationMaxLength: ({ fieldValidationMaxlength }) => fieldValidationMaxlength,
    fieldValidationMinLength: ({ fieldValidationMinlength }) => fieldValidationMinlength,
    fieldValidationMinBytes: ({ fieldValidationMinbytes }) => fieldValidationMinbytes,
    fieldValidationMaxBytes: ({ fieldValidationMaxbytes }) => fieldValidationMaxbytes,
};
export const mutateRelationship = {
    __override__: false,
    ...buildMutateDataForProperty('relationshipSide', ['left', 'right'], { prefix: 'relationship', suffix: 'Side' }),
    ...buildMutateDataForProperty('relationshipType', ['one-to-one', 'one-to-many', 'many-to-one', 'many-to-many'], {
        prefix: 'relationship',
    }),
    collection: ({ relationshipType }) => relationshipType === 'one-to-many' || relationshipType === 'many-to-many',
    relationshipFieldName: ({ relationshipName }) => lowerFirst(relationshipName),
    relationshipFieldNamePlural: ({ relationshipFieldName }) => pluralize(relationshipFieldName, { force: true }),
    relationshipNamePlural: ({ relationshipName }) => pluralize(relationshipName, { force: true }),
    relationshipNameCapitalized: ({ relationshipName }) => upperFirst(relationshipName),
    relationshipNameHumanized: ({ relationshipName }) => startCase(relationshipName),
    propertyName: ({ collection, relationshipFieldName, relationshipFieldNamePlural }) => collection ? relationshipFieldNamePlural : relationshipFieldName,
    ...mutateProperty,
};
export const mutateRelationshipWithEntity = {
    __override__: false,
    otherEntityField: data => data.otherEntity?.primaryKey?.name,
    // let ownerSide true when type is 'many-to-one' for convenience.
    // means that this side should control the reference.
    ownerSide: data => data.otherEntity.embedded || data.relationshipManyToOne || (data.relationshipLeftSide && !data.relationshipOneToMany),
    persistableRelationship: ({ ownerSide }) => ownerSide,
    otherEntityUser: ({ otherEntityName }) => otherEntityName.toLowerCase() === 'user',
};
export const mutateEntity = {
    __override__: false,
    clientRootFolder: '',
    entityNameCapitalized: ({ name }) => upperFirst(name),
    entityNameKebabCase: ({ name }) => kebabCase(name),
    entityNamePlural: ({ name }) => pluralize(name, { force: true }),
    entityNamePluralizedAndSpinalCased: ({ name }) => kebabCase(pluralize(name, { force: false })),
    entityInstance: ({ name }) => lowerFirst(name),
    entityInstancePlural: ({ entityNamePlural }) => lowerFirst(entityNamePlural),
    entityAuthority: ({ adminEntity }) => (adminEntity ? 'ROLE_ADMIN' : undefined),
    entityNameHumanized: ({ entityNameCapitalized }) => startCase(entityNameCapitalized),
    entityNamePluralHumanized: ({ entityNameHumanized }) => pluralize(entityNameHumanized, { force: false }),
};
