"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapBytesWithHelpers = exports.makeBytes = exports.bytesEqual = exports.flexBytesAtOffset = exports.bytesAtOffset = exports.assertFlexBytes = exports.isFlexBytes = exports.assertBytes = exports.hasBytesAtOffset = exports.isBytes = void 0;
const hex_1 = require("./hex");
/**
 * Type guard for `Bytes<T>` type
 *
 * @param b       The byte array
 * @param length  The length of the byte array
 */
function isBytes(b, length) {
    return b instanceof Uint8Array && b.length === length;
}
exports.isBytes = isBytes;
/**
 * Function that verifies if passed data are Bytes and if the array has "length" number of bytes under given offset.
 * @param data
 * @param offset
 * @param length
 */
function hasBytesAtOffset(data, offset, length) {
    if (!(data instanceof Uint8Array)) {
        throw new TypeError('Data has to an Uint8Array!');
    }
    const offsetBytes = data.slice(offset, offset + length);
    return isBytes(offsetBytes, length);
}
exports.hasBytesAtOffset = hasBytesAtOffset;
/**
 * Verifies if a byte array has a certain length
 *
 * @param b       The byte array
 * @param length  The specified length
 */
function assertBytes(b, length) {
    if (!isBytes(b, length)) {
        throw new TypeError(`Parameter is not valid Bytes of length: ${length} !== ${b.length}`);
    }
}
exports.assertBytes = assertBytes;
/**
 * Type guard for FlexBytes<Min,Max> type
 *
 * @param b       The byte array
 * @param min     Minimum size of the array
 * @param max     Maximum size of the array
 */
function isFlexBytes(b, min, max) {
    return b instanceof Uint8Array && b.length >= min && b.length <= max;
}
exports.isFlexBytes = isFlexBytes;
/**
 * Verifies if a byte array has a certain length between min and max
 *
 * @param b       The byte array
 * @param min     Minimum size of the array
 * @param max     Maximum size of the array
 */
function assertFlexBytes(b, min, max) {
    if (!isFlexBytes(b, min, max)) {
        throw new TypeError(`Parameter is not valid FlexBytes of  min: ${min}, max: ${max}, length: ${b.length}`);
    }
}
exports.assertFlexBytes = assertFlexBytes;
/**
 * Return `length` bytes starting from `offset`
 *
 * @param data   The original data
 * @param offset The offset to start from
 * @param length The length of data to be returned
 */
function bytesAtOffset(data, offset, length) {
    const offsetBytes = data.slice(offset, offset + length);
    // We are returning strongly typed Bytes so we have to verify that length is really what we claim
    assertBytes(offsetBytes, length);
    return offsetBytes;
}
exports.bytesAtOffset = bytesAtOffset;
/**
 * Return flex bytes starting from `offset`
 *
 * @param data   The original data
 * @param offset The offset to start from
 * @param _min   The minimum size of the data
 * @param _max   The maximum size of the data
 */
function flexBytesAtOffset(data, offset, 
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_min, 
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_max) {
    return data.slice(offset);
}
exports.flexBytesAtOffset = flexBytesAtOffset;
/**
 * Returns true if two byte arrays are equal
 *
 * @param a Byte array to compare
 * @param b Byte array to compare
 */
function bytesEqual(a, b) {
    return a.length === b.length && a.every((value, index) => value === b[index]);
}
exports.bytesEqual = bytesEqual;
/**
 * Returns a new byte array filled with zeroes with the specified length
 *
 * @param length The length of data to be returned
 */
function makeBytes(length) {
    return new Uint8Array(length);
}
exports.makeBytes = makeBytes;
function wrapBytesWithHelpers(data) {
    return Object.assign(data, {
        text: () => new TextDecoder('utf-8').decode(data),
        json: () => JSON.parse(new TextDecoder('utf-8').decode(data)),
        hex: () => (0, hex_1.bytesToHex)(data),
    });
}
exports.wrapBytesWithHelpers = wrapBytesWithHelpers;
