"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var array_helper_1 = require("../../../core/array-helper");
var util_1 = require("../../../core/util");
var buffer_helper_1 = require("../../../core/buffer/buffer-helper");
var SinglePacket;
(function (SinglePacket) {
    function fillComputedField(packet) {
        if (!packet.sendTime) {
            packet.sendTime = new Date().getTime();
        }
        packet.payload.dataSize = packet.payload.data.length;
        packet.outerHeader.packetLength = util_1.Util.computePadding(packet.payload.data.length + 10, 4) + packet.payload.data.length + 26;
        return packet;
    }
    SinglePacket.fillComputedField = fillComputedField;
    /**
     * TODO shared constant
     */
    SinglePacket.MAX_PART_SIZE = 0xC0;
    // export const MAX_PART_SIZE = 0x80;
    SinglePacket.PACKET_HEADER_SIZE = 22 + 4;
    // export enum Type {
    //     ACKNOWLEDGE = 0x01,
    //     CIPHERED = 0x02
    // }
    // export enum ErrorCode {
    //     PACKET_TOO_SMALL = 0x01
    // }
    // export class PacketTooSmallError extends Error {
    //     code: ErrorCode;
    //     constructor(buffer: , singlePacket: SinglePacketModel) {
    //         super(`SinglePacket is too small. Size must be at least ${(SinglePacket.PACKET_HEADER_SIZE + (singlePacket.dataSize ? singlePacket.dataSize : 0))} but current length is ${buffer.length}`);
    //         this.code = ErrorCode.PACKET_TOO_SMALL;
    //     }
    // }
    /**
     * Utility class to split a big single packet data into {@link SinglePacketPart}
     */
    var Splitter = /** @class */ (function () {
        /**
         * @param chunkSize size (in bytes) of one chunk
         * @param unitBlockSize multiple to compute real size (in bytes)
         * @throws {@link #chunkSize} < {@link #unitBlockSize}
         */
        function Splitter(chunkSize, unitBlockSize) {
            if (unitBlockSize === void 0) { unitBlockSize = Splitter.DEFAULT_BLOCK_SIZE; }
            this.chunkSize = chunkSize;
            this.unitBlockSize = unitBlockSize;
            // Maybe we should force chunk size to be a multiple of unitBlockSize ? 
            if (chunkSize < this.unitBlockSize) {
                throw new Error("Chunk size must be greater than " + this.unitBlockSize + ". Given: " + chunkSize);
            }
            if (chunkSize % unitBlockSize != 0) {
                // TODO error ? 
            }
        }
        /**
         * @return an array of single packet parts
         */
        Splitter.prototype.chunk = function (data) {
            var _this = this;
            var packets = array_helper_1.ArrayHelper.chunk(Array.from(data), this.chunkSize).map(function (value) { return Uint8Array.from(value); });
            var offset = 0;
            return packets.map(function (chunk) {
                var padding = util_1.Util.computePadding(chunk.length, _this.chunkSize);
                if (padding > 0) {
                    chunk = buffer_helper_1.BufferHelper.resize(chunk, chunk.length + padding);
                }
                var part = {
                    data: chunk,
                    len: Math.ceil(chunk.length / _this.unitBlockSize),
                    offset: Math.ceil(offset / _this.unitBlockSize)
                };
                offset += chunk.length;
                return part;
            });
        };
        /**
         * TODO shared constant
         */
        Splitter.DEFAULT_BLOCK_SIZE = 16;
        return Splitter;
    }());
    SinglePacket.Splitter = Splitter;
})(SinglePacket = exports.SinglePacket || (exports.SinglePacket = {}));
