"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.CardinalitySettings = void 0;
const internal_1 = require("../../internal");
const CdmTypeAttributeDefinition_1 = require("../CdmTypeAttributeDefinition");
/**
 * Class for attribute cardinality
 */
// tslint:disable:variable-name
class CardinalitySettings {
    /**
     * CardinalitySettings constructor
     */
    constructor(owner) {
        this.TAG = CardinalitySettings.name;
        /**
         * @internal
         */
        this._minimumNumber = CardinalitySettings.defaultMinimum;
        /**
         * @internal
         */
        this._maximumNumber = CardinalitySettings.defaultMaximum;
        this.owner = owner;
        this.ctx = owner === null || owner === void 0 ? void 0 : owner.ctx;
    }
    /**
     * Minimum cardinality (range -->> "0" .. "n")
     */
    get minimum() {
        return this._minimum;
    }
    set minimum(value) {
        if (internal_1.StringUtils.isNullOrWhiteSpace(value)) {
            internal_1.Logger.error(this.ctx, this.TAG, 'minimum', this.owner.atCorpusPath, internal_1.cdmLogCode.ErrPersistCardinalityPropMissing);
        }
        else if (!CardinalitySettings.isMinimumValid(value)) {
            internal_1.Logger.error(this.ctx, this.TAG, 'minimum', this.owner.atCorpusPath, internal_1.cdmLogCode.ErrValdnInvalidMinCardinality, value);
        }
        else {
            this._minimum = value;
            this._minimumNumber = this.getNumber(this._minimum, CardinalitySettings.defaultMinimum);
            // In the case of type attributes, a '0' minimum cardinality represents a nullable attribute
            if (this.owner && this.owner instanceof CdmTypeAttributeDefinition_1.CdmTypeAttributeDefinition) {
                this.owner.isNullable = (this._minimumNumber === 0);
            }
        }
    }
    /**
     * Maximum cardinality (range -->> "1" .. "*")
     */
    get maximum() {
        return this._maximum;
    }
    set maximum(value) {
        if (internal_1.StringUtils.isNullOrWhiteSpace(value)) {
            internal_1.Logger.error(this.ctx, this.TAG, 'maximum', this.owner.atCorpusPath, internal_1.cdmLogCode.ErrPersistCardinalityPropMissing);
        }
        else if (!CardinalitySettings.isMaximumValid(value)) {
            internal_1.Logger.error(this.ctx, this.TAG, 'maximum', this.owner.atCorpusPath, internal_1.cdmLogCode.ErrValdnInvalidMaxCardinality, value);
        }
        else {
            this._maximum = value;
            this._maximumNumber = this.getNumber(this._maximum, CardinalitySettings.defaultMaximum);
        }
    }
    /**
     * Converts the string cardinality to number
     */
    getNumber(value, defaultValue) {
        if (internal_1.StringUtils.equalsWithIgnoreCase(value, '*')) {
            return CardinalitySettings.infiniteMaximum;
        }
        const number = Number(value);
        if (!isNaN(number)) {
            return number;
        }
        else {
            // defaults to min:max DefaultMinimum:DefaultMaximum in the invalid values
            internal_1.Logger.error(this.ctx, this.TAG, this.getNumber.name, undefined, internal_1.cdmLogCode.ErrProjStringError, value, defaultValue);
            return defaultValue;
        }
    }
    /**
     * Validate if the minimum cardinality is valid
     * Min Cardinality valid options are as follows -- '0'..Int.MaxValue.ToString()
     * By default Min Cardinality is '1'
     * @internal
     */
    static isMinimumValid(minimum) {
        if (minimum) {
            // By default Min Cardinality is 1
            const minNumber = Number(minimum);
            // Min Cardinality valid options are as follows -- '0'..Int.MaxValue.ToString()
            if (isNaN(minNumber)) {
                return false;
            }
            return minNumber >= 0 && minNumber <= Number.MAX_SAFE_INTEGER;
        }
        return false;
    }
    /**
     * Validate if the maximum cardinality is valid
     * Max Cardinality valid options are as follows -- '1'..Int.MaxValue.ToString(), or can be '*' to define Infinity
     * By default Max Cardinality is '1'
     * @internal
     */
    static isMaximumValid(maximum) {
        if (maximum) {
            // By default Max Cardinality is 1
            // Max Cardinality can be '*' to define Infinity
            // If not '*', an explicit value can be provided, but is limited to '1'..Int.MaxValue.ToString()
            if (internal_1.StringUtils.equalsWithIgnoreCase(maximum, '*')) {
                return true;
            }
            const maxNumber = Number(maximum);
            if (isNaN(maxNumber)) {
                return false;
            }
            return maxNumber >= CardinalitySettings.defaultMaximum && maxNumber <= Number.MAX_SAFE_INTEGER;
        }
        return false;
    }
}
exports.CardinalitySettings = CardinalitySettings;
// By default all attributes in CDM are Not Nullable and hence setting the default value to be 1:1
CardinalitySettings.defaultMinimum = 1;
CardinalitySettings.defaultMaximum = 1;
CardinalitySettings.infiniteMaximum = -1;
//# sourceMappingURL=CardinalitySettings.js.map