"use strict";
/*!
  Copyright 2018 Ron Buckton (rbuckton@chronicles.org)

  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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const Debug = require("./debug");
const _1 = require(".");
const guards_1 = require("./guards");
/** @internal */
function fail(ErrorType, paramName, message, stackCrawlMark = fail) {
    const error = new ErrorType(typeof paramName === "string" ? message ? `${message}: ${paramName}` : `Invalid argument: ${paramName}` : message);
    Debug.captureStackTrace(error, stackCrawlMark || assertType);
    throw error;
}
exports.fail = fail;
function assertType(condition, paramName, message, stackCrawlMark = assertType) {
    if (!condition)
        fail(TypeError, paramName, message, stackCrawlMark);
}
function assertRange(condition, paramName, message, stackCrawlMark = assertRange) {
    if (!condition)
        fail(RangeError, paramName, message, stackCrawlMark);
}
function mayBeUndefined(mustBe) {
    return function mayBeUndefined(value, paramName, message, stackCrawlMark = mayBeUndefined) {
        if (value === undefined)
            return;
        mustBe(value, paramName, message, stackCrawlMark);
    };
}
function mayBeNull(mustBe) {
    return function mayBeNull(value, paramName, message, stackCrawlMark = mayBeNull) {
        if (value === null)
            return;
        mustBe(value, paramName, message, stackCrawlMark);
    };
}
/** @internal */
function mustBeBoolean(value, paramName, message, stackCrawlMark = mustBeBoolean) {
    assertType(typeof value === "boolean", paramName, message, stackCrawlMark);
}
exports.mustBeBoolean = mustBeBoolean;
/** @internal */
function mustBeNumber(value, paramName, message, stackCrawlMark = mustBeNumber) {
    assertType(typeof value === "number", paramName, message, stackCrawlMark);
}
exports.mustBeNumber = mustBeNumber;
/** @internal */
function mustBeObject(value, paramName, message = "Object expected", stackCrawlMark = mustBeObject) {
    assertType(_1.IsObject(value), paramName, message, stackCrawlMark);
}
exports.mustBeObject = mustBeObject;
/** @internal */
exports.mustBeObjectOrNull = mayBeNull(mustBeObject);
/** @internal */
function mustBeFunction(value, paramName, message, stackCrawlMark = mustBeFunction) {
    assertType(typeof value === "function", paramName, message, stackCrawlMark);
}
exports.mustBeFunction = mustBeFunction;
/** @internal */
exports.mustBeFunctionOrUndefined = mayBeUndefined(mustBeFunction);
/** @internal */
function mustBeFiniteNumber(value, paramName, message, stackCrawlMark = mustBeFiniteNumber) {
    mustBeNumber(value, paramName, message, stackCrawlMark);
    assertRange(isFinite(value), paramName, message, stackCrawlMark);
}
exports.mustBeFiniteNumber = mustBeFiniteNumber;
/** @internal */
function mustBePositiveFiniteNumber(value, paramName, message, stackCrawlMark = mustBePositiveFiniteNumber) {
    mustBeNumber(value, paramName, message, stackCrawlMark);
    assertRange(isFinite(value) && value >= 0, paramName, message, stackCrawlMark);
}
exports.mustBePositiveFiniteNumber = mustBePositiveFiniteNumber;
/** @internal */
function mustBePositiveNonZeroFiniteNumber(value, paramName, message, stackCrawlMark = mustBePositiveNonZeroFiniteNumber) {
    mustBeNumber(value, paramName, message, stackCrawlMark);
    assertRange(isFinite(value) && value > 0, paramName, message, stackCrawlMark);
}
exports.mustBePositiveNonZeroFiniteNumber = mustBePositiveNonZeroFiniteNumber;
/** @internal */
function mustBeInteger(value, paramName, message, stackCrawlMark = mustBeInteger) {
    mustBeNumber(value, paramName, message, stackCrawlMark);
    assertType(_1.SameValue(value, value | 0), paramName, message, stackCrawlMark);
}
exports.mustBeInteger = mustBeInteger;
/** @internal */
function mustBePositiveInteger(value, paramName, message, stackCrawlMark = mustBePositiveInteger) {
    mustBeNumber(value, paramName, message, stackCrawlMark);
    assertType(_1.SameValue(value, value | 0), paramName, message, stackCrawlMark);
    assertRange(value >= 0, paramName, message, stackCrawlMark);
}
exports.mustBePositiveInteger = mustBePositiveInteger;
/** @internal */
function mustBeIterator(value, paramName, message, stackCrawlMark = mustBeIterator) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    mustBeFunction(value.next, paramName, message, stackCrawlMark);
    exports.mustBeFunctionOrUndefined(value.return, paramName, message, stackCrawlMark);
}
exports.mustBeIterator = mustBeIterator;
/** @internal */
function mustBeQueryable(value, paramName, message = "Iterable or Array-like object expected", stackCrawlMark = mustBeQueryable) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsArrayLike(value) || _1.IsIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeQueryable = mustBeQueryable;
/** @internal */
exports.mustBeQueryableOrUndefined = mayBeUndefined(mustBeQueryable);
/** @internal */
function mustBeAsyncIterable(value, paramName, message = "AsyncIterable object expected", stackCrawlMark = mustBeQueryable) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsAsyncIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeAsyncIterable = mustBeAsyncIterable;
/** @internal */
exports.mustBeAsyncIterableOrUndefined = mayBeUndefined(mustBeAsyncIterable);
/** @internal */
function mustBePossiblyAsyncQueryable(value, paramName, message = "AsyncIterable or Iterable or Array-like object expected", stackCrawlMark = mustBeQueryable) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsArrayLike(value) || _1.IsIterable(value) || _1.IsAsyncIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBePossiblyAsyncQueryable = mustBePossiblyAsyncQueryable;
/** @internal */
exports.mustBePossiblyAsyncQueryableOrUndefined = mayBeUndefined(mustBePossiblyAsyncQueryable);
/** @internal */
function mustBeAsyncQueryable(value, paramName, message = "AsyncIterable or Iterable or Array-like object expected", stackCrawlMark = mustBeQueryable) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsArrayLike(value) || _1.IsIterable(value) || _1.IsAsyncIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeAsyncQueryable = mustBeAsyncQueryable;
/** @internal */
exports.mustBeAsyncQueryableOrUndefined = mayBeUndefined(mustBeAsyncQueryable);
/** @internal */
function mustBeArrayLike(value, paramName, message, stackCrawlMark = mustBeArrayLike) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsArrayLike(value), paramName, message, stackCrawlMark);
}
exports.mustBeArrayLike = mustBeArrayLike;
/** @internal */
function mustBeIterable(value, paramName, message, stackCrawlMark = mustBeArrayLike) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(_1.IsIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeIterable = mustBeIterable;
/** @internal */
function mustBeHierarchyProvider(value, paramName, message, stackCrawlMark = mustBeHierarchyProvider) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    mustBeFunction(value.parent, paramName, message, stackCrawlMark);
    mustBeFunction(value.children, paramName, message, stackCrawlMark);
}
exports.mustBeHierarchyProvider = mustBeHierarchyProvider;
/** @internal */
function mustBeOrderedIterable(value, paramName, message, stackCrawlMark = mustBeOrderedIterable) {
    assertType(_1.IsOrderedIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeOrderedIterable = mustBeOrderedIterable;
/** @internal */
function mustBeOrderedHierarchyIterable(value, paramName, message, stackCrawlMark = mustBeOrderedIterable) {
    assertType(_1.IsOrderedHierarchyIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeOrderedHierarchyIterable = mustBeOrderedHierarchyIterable;
/** @internal */
function mustBeAsyncOrderedIterable(value, paramName, message, stackCrawlMark = mustBeOrderedIterable) {
    assertType(_1.IsAsyncOrderedIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeAsyncOrderedIterable = mustBeAsyncOrderedIterable;
/** @internal */
function mustBePossiblyAsyncOrderedIterable(value, paramName, message, stackCrawlMark = mustBeOrderedIterable) {
    assertType(_1.IsAsyncOrderedIterable(value) || _1.IsOrderedIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBePossiblyAsyncOrderedIterable = mustBePossiblyAsyncOrderedIterable;
/** @internal */
function mustBeHierarchyIterable(value, paramName, message, stackCrawlMark = mustBeHierarchyIterable) {
    assertType(_1.IsHierarchyIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeHierarchyIterable = mustBeHierarchyIterable;
/** @internal */
function mustBeAsyncHierarchyIterable(value, paramName, message, stackCrawlMark = mustBeHierarchyIterable) {
    assertType(guards_1.IsAsyncHierarchyIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBeAsyncHierarchyIterable = mustBeAsyncHierarchyIterable;
/** @internal */
function mustBePossiblyAsyncHierarchyIterable(value, paramName, message, stackCrawlMark = mustBeHierarchyIterable) {
    assertType(_1.IsPossiblyAsyncHierarchyIterable(value), paramName, message, stackCrawlMark);
}
exports.mustBePossiblyAsyncHierarchyIterable = mustBePossiblyAsyncHierarchyIterable;
/** @internal */
function mustBeQuerySource(value, paramName, message, stackCrawlMark = mustBeQuerySource) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(guards_1.IsQuerySource(value), paramName, message, stackCrawlMark);
}
exports.mustBeQuerySource = mustBeQuerySource;
/** @internal */
function mustBeAsyncQuerySource(value, paramName, message, stackCrawlMark = mustBeAsyncQuerySource) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(guards_1.IsAsyncQuerySource(value), paramName, message, stackCrawlMark);
}
exports.mustBeAsyncQuerySource = mustBeAsyncQuerySource;
/** @internal */
function mustBeEqualer(value, paramName, message, stackCrawlMark = mustBeEqualer) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(guards_1.IsEqualer(value), paramName, message, stackCrawlMark);
}
exports.mustBeEqualer = mustBeEqualer;
/** @internal */
exports.mustBeEqualerOrUndefined = mayBeUndefined(mustBeEqualer);
/** @internal */
function mustBeComparer(value, paramName, message, stackCrawlMark = mustBeComparer) {
    mustBeObject(value, paramName, message, stackCrawlMark);
    assertType(guards_1.IsComparer(value), paramName, message, stackCrawlMark);
}
exports.mustBeComparer = mustBeComparer;
/** @internal */
exports.mustBeComparerOrUndefined = mayBeUndefined(mustBeComparer);
//# sourceMappingURL=assert.js.map