import { InvariantCulture } from "./culture-info";
const primitiveTypeNames = ["null", "undefined", "string", "number", "bigint", "boolean", "symbol"];
// eslint-disable-next-line @typescript-eslint/ban-types
function isOfType(type) {
    return (value) => typeof value === type;
}
const isString = isOfType("string");
const isNumberType = isOfType("number");
const isNumber = (value) => isNumberType(value) && !Number.isNaN(value);
const isInfinite = (value) => value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY;
export class Guard {
    static notNull(value, valueName) {
        if (value === null)
            throw `${valueName ? valueName : "Value"} should not be null.`;
    }
    static notUndefined(value, valueName) {
        if (value === undefined)
            throw `${valueName ? valueName : "Value"} should not be undefined.`;
    }
    static notNullOrUndefined(value, valueName) {
        if (value === null || value === undefined)
            throw Error(`${valueName ? valueName : "Value"} should not be null or undefined. Value is ${value === null ? "null" : "undefined"}.`);
    }
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
    static parsableInteger(value, valueName) {
        const parsedValue = parseInt(value);
        if (isNaN(parsedValue) || parsedValue.toString() !== value.toString()) {
            throw Error(`${valueName ? valueName : `Value '${value}'`} can not be parsed to an integer.`);
        }
    }
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
    static parsableFloat(value, valueName) {
        const parsedValue = parseFloat(value);
        if (isNaN(parsedValue) || parsedValue.toString() !== value.toString()) {
            throw Error(`${valueName ? valueName : `Value '${value}'`} can not be parsed to a float/decimal.`);
        }
    }
    // Values
    static isString(value, valueName) {
        if (isString(value)) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be a string, got ${value}`);
    }
    static isInteger(value, valueName) {
        if (Number.isInteger(value)) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be an integer, got ${value}`);
    }
    // Arrays
    static arrayNotEmpty(value, valueName) {
        if (Array.isArray(value) && value.length > 0) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to not be empty`);
    }
    static arrayMaxOne(value, valueName) {
        if (Array.isArray(value) && value.length <= 1) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to have a maximum length of 1, got \`${value.length}\``);
    }
    static arrayNoneNullOrUndefined(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(item => item == null)) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""}should not contain null or undefined.`);
        }
    }
    static arrayNoneNullOrEmptyString(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(item => item == null || (typeof item === "string" && (item.length === 0 || item.trim().length === 0)))) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""}should not contain null, undefined or empty string.`);
        }
    }
    static arrayNoneNullOrInvariantCulture(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(culture => culture == null || culture === InvariantCulture)) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""}should not contain null, undefined or '${InvariantCulture}'.`);
        }
    }
    static isStringArray(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(value => typeof value !== "string")) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""}should only contain values of type string.`);
        }
    }
    static isIntegerArray(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(value => typeof value !== "number" || !Number.isInteger(value))) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""}should only contain values of type number.`);
        }
    }
    static isNumberArray(value, valueName, isOptional = false) {
        if (!isOptional) {
            Guard.notNullOrUndefined(value);
        }
        else if (value == null) {
            return;
        }
        if (!Array.isArray(value)) {
            throw Error(`Value ${valueName ? ` '${valueName}' ` : ""}is not an array.`);
        }
        else if (value.some(value => typeof value !== "number")) {
            throw Error(`Array ${valueName ? ` '${valueName}' ` : ""} should only contain values of type number.`);
        }
    }
    // Strings
    static stringNotNullOrEmpty(value, valueName) {
        Guard.notNullOrUndefined(value, valueName);
        Guard.isString(value, valueName);
        if ((value === null || value === void 0 ? void 0 : value.trim().length) === 0) {
            throw Error(`Expected ${valueName ? `'${valueName}'` : ""} not to be an empty or all whitespace string ('${value}').`);
        }
    }
    // Ids
    static validId(value, valueName) {
        Guard.isInteger(value, valueName);
        if (!isInfinite(value) && value > 0) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}' ` : ""} to be a positive integer, got '${value}'.`);
    }
    static validIdOrNull(value, valueName) {
        if (value === null) {
            return;
        }
        Guard.validId(value, valueName);
    }
    static validIds(value, valueName) {
        if (Array.isArray(value) && value.length === 0) {
            return;
        }
        Guard.isIntegerArray(value, valueName);
        value.some(value => Guard.validId(value, valueName));
    }
    // Cultures
    static notInvariantCulture(culture, valueName) {
        Guard.stringNotNullOrEmpty(culture, valueName);
        if (culture !== InvariantCulture) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to not be equal to '${InvariantCulture}', got '${culture}'.`);
    }
    // Numbers
    static notNegative(value, valueName) {
        if (isNumber(value) && value >= 0) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be positive, got '${value}'.`);
    }
    static greaterThan(number, minValue, valueName) {
        if (isNumber(number) && number > minValue) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be greater than ${minValue}, got '${number}'.`);
    }
    static greaterThanOrEqual(number, minValue, valueName) {
        if (isNumber(number) && number >= minValue) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be greater than or equal to ${minValue}, got '${number}'.`);
    }
    static lessThan(number, maxValue, valueName) {
        if (isNumber(number) && number < maxValue) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be less than ${maxValue}, got '${number}'.`);
    }
    static lessThanOrEqual(number, maxValue, valueName) {
        if (isNumber(number) && number <= maxValue) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be less than or equal to ${maxValue}, got '${number}'.`);
    }
    static isNumber(value, valueName) {
        if (isNumber(value)) {
            return;
        }
        throw Error(`Expected ${valueName ? `'${valueName}'` : ""} to be number, got '${value}'.`);
    }
}
export default Guard;
//# sourceMappingURL=guard.js.map