"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module ECSQL
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ECJsNames = exports.ECSqlSystemProperty = exports.ChangedValueState = exports.ChangeOpCode = exports.ECSqlValueType = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
/** Describes the different data types an ECSQL value can be of.
 * See also [ECSQL]($docs/learning/ECSQL).
 * @public
 * @extensions
 */
var ECSqlValueType;
(function (ECSqlValueType) {
    // do not change the values of the enum as it must match its counterpart in the addon
    ECSqlValueType[ECSqlValueType["Blob"] = 1] = "Blob";
    ECSqlValueType[ECSqlValueType["Boolean"] = 2] = "Boolean";
    ECSqlValueType[ECSqlValueType["DateTime"] = 3] = "DateTime";
    ECSqlValueType[ECSqlValueType["Double"] = 4] = "Double";
    ECSqlValueType[ECSqlValueType["Geometry"] = 5] = "Geometry";
    ECSqlValueType[ECSqlValueType["Id"] = 6] = "Id";
    ECSqlValueType[ECSqlValueType["Int"] = 7] = "Int";
    ECSqlValueType[ECSqlValueType["Int64"] = 8] = "Int64";
    ECSqlValueType[ECSqlValueType["Point2d"] = 9] = "Point2d";
    ECSqlValueType[ECSqlValueType["Point3d"] = 10] = "Point3d";
    ECSqlValueType[ECSqlValueType["String"] = 11] = "String";
    ECSqlValueType[ECSqlValueType["Navigation"] = 12] = "Navigation";
    ECSqlValueType[ECSqlValueType["Struct"] = 13] = "Struct";
    ECSqlValueType[ECSqlValueType["PrimitiveArray"] = 14] = "PrimitiveArray";
    ECSqlValueType[ECSqlValueType["StructArray"] = 15] = "StructArray";
    ECSqlValueType[ECSqlValueType["Guid"] = 16] = "Guid";
})(ECSqlValueType || (exports.ECSqlValueType = ECSqlValueType = {}));
/** Equivalent of the ECEnumeration OpCode in the **ECDbChange** ECSchema.
 * The enum can be used when programmatically binding values to the InstanceChange.OpCode property of
 * the ECDbChange ECSchema.
 *
 * See also
 * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)
 * @public
 * @extensions
 */
var ChangeOpCode;
(function (ChangeOpCode) {
    ChangeOpCode[ChangeOpCode["Insert"] = 1] = "Insert";
    ChangeOpCode[ChangeOpCode["Update"] = 2] = "Update";
    ChangeOpCode[ChangeOpCode["Delete"] = 4] = "Delete";
})(ChangeOpCode || (exports.ChangeOpCode = ChangeOpCode = {}));
/** The enum represents the values for the ChangedValueState argument of the ECSQL function **Changes**.
 * The enum can be used when programmatically binding values to the ChangedValueState argument
 * in an ECSQL using the **Changes** ECSQL function.
 *
 * See also
 * - [ChangeSummary Overview]($docs/learning/ChangeSummaries)
 * @public
 * @extensions
 */
var ChangedValueState;
(function (ChangedValueState) {
    ChangedValueState[ChangedValueState["AfterInsert"] = 1] = "AfterInsert";
    ChangedValueState[ChangedValueState["BeforeUpdate"] = 2] = "BeforeUpdate";
    ChangedValueState[ChangedValueState["AfterUpdate"] = 3] = "AfterUpdate";
    ChangedValueState[ChangedValueState["BeforeDelete"] = 4] = "BeforeDelete";
})(ChangedValueState || (exports.ChangedValueState = ChangedValueState = {}));
/** Defines the ECSQL system properties.
 * See also [ECSQL]($docs/learning/ECSQL).
 * @public
 * @extensions
 */
var ECSqlSystemProperty;
(function (ECSqlSystemProperty) {
    ECSqlSystemProperty[ECSqlSystemProperty["ECInstanceId"] = 0] = "ECInstanceId";
    ECSqlSystemProperty[ECSqlSystemProperty["ECClassId"] = 1] = "ECClassId";
    ECSqlSystemProperty[ECSqlSystemProperty["SourceECInstanceId"] = 2] = "SourceECInstanceId";
    ECSqlSystemProperty[ECSqlSystemProperty["SourceECClassId"] = 3] = "SourceECClassId";
    ECSqlSystemProperty[ECSqlSystemProperty["TargetECInstanceId"] = 4] = "TargetECInstanceId";
    ECSqlSystemProperty[ECSqlSystemProperty["TargetECClassId"] = 5] = "TargetECClassId";
    ECSqlSystemProperty[ECSqlSystemProperty["NavigationId"] = 6] = "NavigationId";
    ECSqlSystemProperty[ECSqlSystemProperty["NavigationRelClassId"] = 7] = "NavigationRelClassId";
    ECSqlSystemProperty[ECSqlSystemProperty["PointX"] = 8] = "PointX";
    ECSqlSystemProperty[ECSqlSystemProperty["PointY"] = 9] = "PointY";
    ECSqlSystemProperty[ECSqlSystemProperty["PointZ"] = 10] = "PointZ";
})(ECSqlSystemProperty || (exports.ECSqlSystemProperty = ECSqlSystemProperty = {}));
/** Utility to format ECProperty names according to the iTwin.js formatting rules.
 * See also [ECSQL Row Format]($docs/learning/ECSQLRowFormat).
 * @public
 */
class ECJsNames {
    /** Formats the specified ECProperty name according to the iTwin.js formatting rules.
     *
     *  See [ECSQL Row Format]($docs/learning/ECSQLRowFormat) which describes the formatting rules.
     *
     * @param ecProperty Property name as defined in the ECSchema for regular ECProperties
     *        or the name of an ECSQL system properties
     * @param isSystemProperty if omitted, the method will try to find out whether the given property
     *        is a system property or not. If true is specified, the method will throw if the property name
     *        is not a known system property. If false is specified, the method will not attempt to recognize
     *        the property name as system property.
     */
    static toJsName(propName, isSystemProperty) {
        (0, core_bentley_1.assert)(propName !== undefined, "propName must not be undefined");
        const propTypeUnknown = isSystemProperty === undefined || isSystemProperty === null;
        const accessStringTokens = propName.split(".");
        const tokenCount = accessStringTokens.length;
        (0, core_bentley_1.assert)(tokenCount > 0);
        if (tokenCount === 1) {
            if (propTypeUnknown || isSystemProperty) {
                if (propName === "ECInstanceId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.ECInstanceId);
                if (propName === "ECClassId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.ECClassId);
                if (propName === "SourceECInstanceId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.SourceECInstanceId);
                if (propName === "TargetECInstanceId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.TargetECInstanceId);
                if (propName === "SourceECClassId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.SourceECClassId);
                if (propName === "TargetECClassId")
                    return ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.TargetECClassId);
                return ECJsNames.lowerFirstChar(propName);
            }
            return ECJsNames.lowerFirstChar(propName);
        }
        // parse access string and convert the leaf tokens if they are system props
        // The first char of the access string is lowered.
        let jsName = ECJsNames.lowerFirstChar(`${accessStringTokens[0]}.`);
        for (let j = 1; j < tokenCount - 1; j++) {
            jsName += `${accessStringTokens[j]}.`;
        }
        const leafToken = accessStringTokens[tokenCount - 1];
        if (propTypeUnknown || isSystemProperty) {
            if (leafToken === "Id")
                jsName += ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.NavigationId);
            else if (leafToken === "RelECClassId")
                jsName += ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.NavigationRelClassId);
            else if (leafToken === "X")
                jsName += ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.PointX);
            else if (leafToken === "Y")
                jsName += ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.PointY);
            else if (leafToken === "Z")
                jsName += ECJsNames.systemPropertyToJsName(ECSqlSystemProperty.PointZ);
            else if (propTypeUnknown)
                jsName += ECJsNames.lowerFirstChar(leafToken);
            else
                throw new Error(`Property ${leafToken} of access string ${propName} is no ECSQL system property.`);
        }
        else
            jsName += leafToken;
        return jsName;
    }
    /** Returns the name of the specified ECSQL system property according to the
     *  iTwin.js formatting rules.
     *
     *  See [ECSQL Row Format]($docs/learning/ECSQLRowFormat) which describes the formatting rules.
     * @param systemPropertyType System property type
     */
    static systemPropertyToJsName(systemPropertyType) {
        switch (systemPropertyType) {
            case ECSqlSystemProperty.ECInstanceId:
            case ECSqlSystemProperty.NavigationId:
                return "id";
            case ECSqlSystemProperty.ECClassId:
                return "className";
            case ECSqlSystemProperty.SourceECInstanceId:
                return "sourceId";
            case ECSqlSystemProperty.SourceECClassId:
                return "sourceClassName";
            case ECSqlSystemProperty.TargetECInstanceId:
                return "targetId";
            case ECSqlSystemProperty.TargetECClassId:
                return "targetClassName";
            case ECSqlSystemProperty.NavigationRelClassId:
                return "relClassName";
            case ECSqlSystemProperty.PointX:
                return "x";
            case ECSqlSystemProperty.PointY:
                return "y";
            case ECSqlSystemProperty.PointZ:
                return "z";
            default:
                throw new Error(`Unknown ECSqlSystemProperty enum value ${systemPropertyType}.`);
        }
    }
    static lowerFirstChar(name) { return name[0].toLowerCase() + name.substring(1); }
}
exports.ECJsNames = ECJsNames;
//# sourceMappingURL=ECSqlTypes.js.map