/**
 * 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 { DATE_FORMAT, ELEMENT_PATH_DELIMITER, MULTIPLICITY_INFINITE, MULTIPLICITY_RANGE_OPERATOR, PRIMITIVE_TYPE, } from '../MetaModelConst.js';
import { PrimitiveType } from '../metamodel/pure/packageableElements/domain/PrimitiveType.js';
import { Enumeration } from '../metamodel/pure/packageableElements/domain/Enumeration.js';
import { formatDate } from '@finos/legend-shared';
export var PURE_ELEMENT_NAME;
(function (PURE_ELEMENT_NAME) {
    PURE_ELEMENT_NAME["PROFILE"] = "Profile";
    PURE_ELEMENT_NAME["CLASS"] = "Class";
    PURE_ELEMENT_NAME["ENUMERATION"] = "Enum";
    PURE_ELEMENT_NAME["MEASURE"] = "Measure";
    PURE_ELEMENT_NAME["ASSOCIATION"] = "Association";
    PURE_ELEMENT_NAME["FUNCTION"] = "function";
    PURE_ELEMENT_NAME["MAPPING"] = "Mapping";
    PURE_ELEMENT_NAME["FLAT_DATA"] = "FlatData";
    PURE_ELEMENT_NAME["DATABASE"] = "Database";
    PURE_ELEMENT_NAME["SERVICE"] = "Service";
    PURE_ELEMENT_NAME["RUNTIME"] = "Runtime";
    PURE_ELEMENT_NAME["CONNECTION"] = "Connection";
    PURE_ELEMENT_NAME["FILE_GENERATION"] = "FileGeneration";
    PURE_ELEMENT_NAME["GENERATION_SPECIFICATION"] = "GenerationSpecification";
    PURE_ELEMENT_NAME["DATA_ELEMENT"] = "Data";
    PURE_ELEMENT_NAME["EXECUTION_ENVIRONMENT"] = "ExecutionEnvironment";
})(PURE_ELEMENT_NAME || (PURE_ELEMENT_NAME = {}));
export var PURE_CONNECTION_NAME;
(function (PURE_CONNECTION_NAME) {
    PURE_CONNECTION_NAME["JSON_MODEL_CONNECTION"] = "JsonModelConnection";
    PURE_CONNECTION_NAME["XML_MODEL_CONNECTION"] = "XmlModelConnection";
    PURE_CONNECTION_NAME["MODEL_CHAIN_CONNECTION"] = "ModelChainConnection";
    PURE_CONNECTION_NAME["RELATIONAL_DATABASE_CONNECTION"] = "RelationalDatabaseConnection";
    PURE_CONNECTION_NAME["FLAT_DATA_CONNECTION"] = "FlatDataConnection";
})(PURE_CONNECTION_NAME || (PURE_CONNECTION_NAME = {}));
export var PURE_PARSER;
(function (PURE_PARSER) {
    PURE_PARSER["PURE"] = "Pure";
    PURE_PARSER["CONNECTION"] = "Connection";
    PURE_PARSER["RUNTIME"] = "Runtime";
    PURE_PARSER["MAPPING"] = "Mapping";
    PURE_PARSER["SERVICE"] = "Service";
    PURE_PARSER["FLATDATA"] = "FlatData";
    PURE_PARSER["RELATIONAL"] = "Relational";
    PURE_PARSER["GENERATION_SPECIFICATION"] = "GenerationSpecification";
    PURE_PARSER["FILE_GENERATION_SPECIFICATION"] = "FileGeneration";
    PURE_PARSER["DATA"] = "Data";
})(PURE_PARSER || (PURE_PARSER = {}));
export const generateMultiplicityString = (lowerBound, upperBound) => {
    if (lowerBound === upperBound) {
        return lowerBound.toString();
    }
    else if (lowerBound === 0 && upperBound === undefined) {
        return MULTIPLICITY_INFINITE;
    }
    return `${lowerBound}${MULTIPLICITY_RANGE_OPERATOR}${upperBound ?? MULTIPLICITY_INFINITE}`;
};
export const generateDefaultParameterValueForType = (type, index) => {
    if (!type) {
        return `param${index}`;
    }
    if (type instanceof Enumeration) {
        return type.values.length !== 0
            ? `${type.path}.${type.values[0]?.name}`
            : `param${index}`;
    }
    else if (type instanceof PrimitiveType) {
        switch (type.name) {
            case PRIMITIVE_TYPE.BOOLEAN:
                return true;
            case PRIMITIVE_TYPE.FLOAT:
            case PRIMITIVE_TYPE.DECIMAL:
                return 0.0;
            case PRIMITIVE_TYPE.NUMBER:
            case PRIMITIVE_TYPE.INTEGER:
                return 0;
            case PRIMITIVE_TYPE.DATE:
            case PRIMITIVE_TYPE.STRICTDATE:
                return `%${formatDate(new Date(), DATE_FORMAT)}`;
            case PRIMITIVE_TYPE.DATETIME:
                return `%${formatDate(new Date(), DATE_FORMAT)}T00:00:00`;
            case PRIMITIVE_TYPE.STRICTTIME:
                return `%00:00:00`;
            case PRIMITIVE_TYPE.STRING:
                return "''";
            default:
                return `param${index}`;
        }
    }
    // Other non-primitive types, e.g. Class
    return `param${index}`;
};
export const generateFunctionCallString = (element) => {
    let lambdaString = '';
    if (element.parameters.length > 0) {
        for (let i = 0; i < element.parameters.length; i++) {
            const paramType = element.parameters[i]?.type.value;
            const separator = i !== element.parameters.length - 1 ? ', ' : '';
            lambdaString =
                lambdaString +
                    generateDefaultParameterValueForType(paramType, i) +
                    separator;
        }
    }
    return `${element.package?.path}${ELEMENT_PATH_DELIMITER}${element.functionName}(${lambdaString})`;
};
export const generateFunctionCallStringFromFunctionAnalysisInfo = (graph, functionInfo) => {
    let lambdaString = '';
    const parameterLength = functionInfo.parameterInfoList.length;
    if (parameterLength > 0) {
        for (let i = 0; i < parameterLength; i++) {
            const info = functionInfo.parameterInfoList[i];
            let paramType;
            if (info !== undefined) {
                try {
                    paramType = graph.getType(info.type);
                }
                catch {
                    // graph might not contain classes used as type, do nothing here
                }
            }
            const separator = i !== parameterLength - 1 ? ', ' : '';
            lambdaString =
                lambdaString +
                    generateDefaultParameterValueForType(paramType, i) +
                    separator;
        }
    }
    return `${functionInfo.packagePath}${ELEMENT_PATH_DELIMITER}${functionInfo.functionName}(${lambdaString})`;
};
export const generateGenericTypeString = (type) => {
    return (type.rawType.name +
        (type.typeArguments?.length
            ? `<${type.typeArguments.map((t) => generateGenericTypeString(t.value)).join(', ')}>`
            : ''));
};
export const generateFunctionPrettyName = (element, options) => `${options?.fullPath ? `${element.package?.path}${ELEMENT_PATH_DELIMITER}` : ''}${element.functionName}(${element.parameters
    .map((p) => !options?.notIncludeParamName
    ? `${p.name}: ${p.type.value.name}[${generateMultiplicityString(p.multiplicity.lowerBound, p.multiplicity.upperBound)}]`
    : `${p.type.value.name}[${generateMultiplicityString(p.multiplicity.lowerBound, p.multiplicity.upperBound)}]`)
    .join(', ')}): ${generateGenericTypeString(element.returnType.value)}[${generateMultiplicityString(element.returnMultiplicity.lowerBound, element.returnMultiplicity.upperBound)}]`.replaceAll(/\s*/gu, (val) => {
    if (options?.spacing) {
        return val;
    }
    return '';
});
//# sourceMappingURL=PureLanguageHelper.js.map