"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ArgumentError_1 = __importDefault(require("../exception/ArgumentError"));
const messages_1 = require("./messages");
const pattern_1 = __importDefault(require("./pattern"));
/**
 * Validate that the argument condition is [true] otherwise
 * throwing an exception with the specified message. This method is useful when
 * validating according to an arbitrary boolean expression, such as validating a
 * primitive number or using your own custom validation expression.
 *
 * @param expression The boolean expression to check
 * @param message the exception message if invalid, not null
 *
 * @return evaluated expression
 *
 * @throws Throws [ArgumentError] if expression is [false]
 */
function isTrue(expression, message = messages_1.DEFAULT_IS_TRUE_MESSAGE) {
    if (!expression) {
        throw new ArgumentError_1.default(message());
    }
    return expression;
}
exports.isTrue = isTrue;
/**
 * Validate that the specified argument is not [null];
 * otherwise throwing an exception.
 *
 *      Validate.notNull(myObject, () => "The object must not be null");
 *
 * The message of the exception is &quot;The validated object is
 * null&quot;.
 *
 * @param expression The expression the should evaluate against null
 * @param message The exception message if invalid
 *
 * @return evaluated expression
 *
 * @throws Throws [ArgumentError] if expression is null
 */
function notNull(expression, message = messages_1.DEFAULT_IS_NULL_MESSAGE) {
    if (expression === null || expression === undefined) {
        throw new ArgumentError_1.default(message());
    }
    return expression;
}
exports.notNull = notNull;
/**
 * Validate that the specified argument is neither null
 * nor is empty.
 *
 * @param expression The expression the should evaluate against not being empty
 * @param message The exception message if invalid
 *
 * @return evaluated expression
 *
 * @throws Throws [ArgumentError] if expression is invalid
 */
function notEmpty(expression, message = messages_1.DEFAULT_NOT_EMPTY_MESSAGE) {
    notNull(expression);
    // tslint:disable-next-line
    if (expression.hasOwnProperty('length') && expression.length === 0) {
        throw new ArgumentError_1.default(message());
    }
    else if (typeof expression === 'object' && Object.keys(expression).length === 0) {
        throw new ArgumentError_1.default(message());
    }
    return expression;
}
exports.notEmpty = notEmpty;
/**
 * Validate that the specified string is
 * neither null, a length of zero (no characters), empty
 * nor whitespace; otherwise throwing an exception with the specified
 * message.
 *
 * @param expression The expression the should evaluate against not being blank
 * @param message The exception message if invalid
 *
 * @return evaluated expression
 *
 * @throws Throws [ArgumentError] if expression is invalid
 */
function notBlank(expression, message = messages_1.DEFAULT_NOT_BLANK_MESSAGE) {
    notNull(expression);
    if (expression.trim().length === 0) {
        throw new ArgumentError_1.default(message());
    }
    return expression;
}
exports.notBlank = notBlank;
/**
 * Validates that the given [index] is available in the given [array]
 * and its value is not null or undefined.
 *
 * @param index Array-Index
 * @param array The Array to check against
 * @param message The exception message if invalid
 *
 * @return If the index is valid it is returned
 *
 * @throws Throws [ArgumentError] if expression is invalid
 */
function isIndexValid(index, array, message = messages_1.DEFAULT_INVALID_INDEX_MESSAGE(index, array)) {
    notNull(array);
    if (index < 0 || index >= array.length || !array[index]) {
        throw new ArgumentError_1.default(message());
    }
    return index;
}
exports.isIndexValid = isIndexValid;
/**
 * Validates that the given [property] is available in the given [obj]
 * and its value is not null or undefined.
 *
 * @param key Property in [obj]
 * @param obj The object to check the property against
 * @param message The exception message if invalid
 *
 * @return If the key is valid it is returned
 *
 * @throws Throws [ArgumentError] if expression is invalid
 */
function isPropertyValid(key, obj, message = messages_1.DEFAULT_INVALID_PROPERTY_MESSAGE(key, obj)) {
    notNull(obj);
    // tslint:disable-next-line
    if (!(key in obj) || !obj[key]) {
        throw new ArgumentError_1.default(message());
    }
    return key;
}
exports.isPropertyValid = isPropertyValid;
/**
 * Validate that the specified [input] matches the specified [regex] pattern;
 * otherwise throwing an exception.
 *
 * @param input String to check against the given [regex]
 * @param regexp The Pattern to check the string against
 * @param message The exception message if invalid
 *
 * @return If the key is valid it is returned
 *
 * @throws Throws [ArgumentError] if expression is invalid
 */
function matchesPattern(input, regexp, message = messages_1.DEFAULT_MATCHES_PATTERN(input, regexp)) {
    notNull(regexp);
    if (!regexp.test(input)) {
        throw new ArgumentError_1.default(message());
    }
    return true;
}
exports.matchesPattern = matchesPattern;
function isEmail(email, message = messages_1.DEFAULT_MATCHES_EMAIL(email)) {
    return matchesPattern(email, pattern_1.default.EMAIL, message);
}
exports.isEmail = isEmail;
function isPassword(password, message = messages_1.DEFAULT_MATCHES_PASSWORD(password)) {
    return matchesPattern(password, pattern_1.default.PW, message);
}
exports.isPassword = isPassword;
function isAlphanumeric(value, message = messages_1.DEFAULT_MATCHES_ALPHANUMERIC(value)) {
    return matchesPattern(value, pattern_1.default.ALPHANUMERIC, message);
}
exports.isAlphanumeric = isAlphanumeric;
function isHex(value, message = messages_1.DEFAULT_MATCHES_HEX(value)) {
    return matchesPattern(value, pattern_1.default.HEX, message);
}
exports.isHex = isHex;
function isUuid(value, message = messages_1.DEFAULT_MATCHES_UUID(value)) {
    return matchesPattern(value, pattern_1.default.UUID, message);
}
exports.isUuid = isUuid;
//# sourceMappingURL=validate.js.map