/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * 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
 *
 *     http://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 { UnsupportedOperationError } from '@finos/legend-shared';
import { generateMultiplicityString } from '../../../../../graph/helpers/PureLanguageHelper.js';
import { ELEMENT_PATH_DELIMITER, FUNCTION_SIGNATURE_MULTIPLICITY_INFINITE_TOKEN, } from '../../../../../graph/MetaModelConst.js';
import { V1_Multiplicity } from '../model/packageableElements/domain/V1_Multiplicity.js';
import { V1_GenericType } from '../model/packageableElements/type/V1_GenericType.js';
import { V1_PackageableType } from '../model/packageableElements/type/V1_PackageableType.js';
import { V1_RelationType, V1_RelationTypeColumn, } from '../model/packageableElements/type/V1_RelationType.js';
import { V1_transformMultiplicity } from '../transformation/pureGraph/from/V1_CoreTransformerHelper.js';
export const V1_getGenericTypeFullPath = (val) => {
    if (val.rawType instanceof V1_PackageableType) {
        return val.rawType.fullPath;
    }
    else if (val.rawType instanceof V1_RelationType) {
        return V1_RelationType.NAME;
    }
    throw new UnsupportedOperationError(`Can't extract type path from generic type`);
};
const V1_buildFunctionMultiplicitySignature = (multiplicity) => {
    if (multiplicity.lowerBound === multiplicity.upperBound) {
        return multiplicity.lowerBound.toString();
    }
    else if (multiplicity.lowerBound === 0 &&
        multiplicity.upperBound === undefined) {
        return FUNCTION_SIGNATURE_MULTIPLICITY_INFINITE_TOKEN;
    }
    return `$${multiplicity.lowerBound}_${multiplicity.upperBound ?? FUNCTION_SIGNATURE_MULTIPLICITY_INFINITE_TOKEN}$`;
};
const V1_buildFunctionParameterSignature = (variable) => `${variable.genericType.rawType.fullPath
    .split(ELEMENT_PATH_DELIMITER)
    .pop()}_${V1_buildFunctionMultiplicitySignature(variable.multiplicity)}_`;
export const V1_buildFunctionSignatureSuffix = (func) => `_${func.parameters
    .map((p) => V1_buildFunctionParameterSignature(p))
    .join('_')}_${V1_getGenericTypeFullPath(func.returnGenericType)
    .split(ELEMENT_PATH_DELIMITER)
    .pop()}_${V1_buildFunctionMultiplicitySignature(func.returnMultiplicity)}_`;
export const V1_buildFunctionSignature = (func) => {
    const functionSignature = V1_buildFunctionSignatureSuffix(func);
    return func.name.endsWith(functionSignature)
        ? func.name
        : func.name + functionSignature;
};
export const V1_getFunctionNameWithoutSignature = (func) => {
    const signatureSuffix = V1_buildFunctionSignatureSuffix(func);
    return func.name.endsWith(signatureSuffix)
        ? func.name.substring(0, func.name.length - signatureSuffix.length)
        : func.name;
};
export const V1_buildFunctionPrettyName = (element, options) => `${options?.fullPath ? `${element.package}${ELEMENT_PATH_DELIMITER}` : ''}${element.name.substring(0, element.name.indexOf(V1_buildFunctionSignatureSuffix(element)))}(${element.parameters
    .map((p) => !options?.notIncludeParamName
    ? `${p.name}: ${p.genericType.rawType.fullPath}[${generateMultiplicityString(p.multiplicity.lowerBound, p.multiplicity.upperBound)}]`
    : `${p.genericType.rawType.fullPath}[${generateMultiplicityString(p.multiplicity.lowerBound, p.multiplicity.upperBound)}]`)
    .join(', ')}): ${V1_getGenericTypeFullPath(element.returnGenericType)}[${generateMultiplicityString(element.returnMultiplicity.lowerBound, element.returnMultiplicity.upperBound)}]`.replaceAll(/\s*/gu, (val) => {
    if (options?.spacing) {
        return val;
    }
    return '';
});
export function V1_createRelationType(columns) {
    const relationType = new V1_RelationType();
    relationType.columns = columns;
    return relationType;
}
export function V1_createRelationTypeColumn(name, type, typeVariableValues) {
    const column = new V1_RelationTypeColumn();
    column.name = name;
    column.genericType = V1_createGenericTypeWithElementPath(type, typeVariableValues);
    column.multiplicity = V1_Multiplicity.ZERO_ONE;
    return column;
}
export function V1_createRelationTypeColumnWithGenericType(name, type, multiplicity) {
    const column = new V1_RelationTypeColumn();
    column.name = name;
    column.genericType = type;
    column.multiplicity = V1_transformMultiplicity(multiplicity);
    return column;
}
export function V1_createGenericTypeWithElementPath(path, typeVariables) {
    const genType = new V1_GenericType();
    const pType = new V1_PackageableType();
    pType.fullPath = path;
    genType.rawType = pType;
    genType.typeVariableValues = typeVariables ?? [];
    return genType;
}
export function V1_createGenericTypeWithRawType(type) {
    const genType = new V1_GenericType();
    genType.rawType = type;
    return genType;
}
//# sourceMappingURL=V1_DomainHelper.js.map