/**
 * Created by xiaoqiang on 2018/7/30.
 */
var Utils = {
    buffer: null,
    getLocalIP: function () {
        return null;
    },
    arrayBufferToBase64: function (bytes) {
        var binary = '';
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
    },
    Utf8ArrayToStr: function (array) {
        var out, i, len, c;
        var char2, char3;
        out = "";
        len = array.length;
        i = 0;
        while (i < len) {
            c = array[i++];
            switch (c >> 4) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    // 0xxxxxxx
                    out += String.fromCharCode(c);
                    break;
                case 12:
                case 13:
                    // 110x xxxx   10xx xxxx
                    char2 = array[i++];
                    out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                    break;
                case 14:
                    // 1110 xxxx  10xx xxxx  10xx xxxx
                    char2 = array[i++];
                    char3 = array[i++];
                    out += String.fromCharCode(((c & 0x0F) << 12) |
                        ((char2 & 0x3F) << 6) |
                        ((char3 & 0x3F) << 0));
                    break;
            }
        }
        return out;
    },
    _findCarriageSemicolon: function (buf, startPos) {
        for (var i = startPos; i < buf.length; i++) {
            if (buf[i] === 59) { // L:44;xxxxxxxxx
                return i;
            }
        }
        return -1;
    },
    /**
     * 接收的数据结构如下
     * L: + message_length + | + binary_length + ; + message + binary + \r\n
     */
    parseReceived: function (dataBuf) {
        var data = new Uint8Array(dataBuf);
        if (this.buffer) {
            data = ArrayBuffer.concat([this.buffer, data]);
            this.buffer = null;
        }
        var messages = [];
        var pos = 0;
        var total = data.byteLength;
        while (total - pos > 4) {
            // 检查是否以L:开头
            if (data[pos] !== 76 || data[pos + 1] !== 58) {
                var slice = data.subarray(pos, pos + 2);
                throw new Error("Missing length header in received data: " + slice);
            }
            // 找到头部(;位置)长度
            var endOfLengthHeader = this._findCarriageSemicolon(data, pos + 2);
            if (endOfLengthHeader === -1 || data.length == endOfLengthHeader) {
                break;
            }
            // L:(messageLengthStr.length|payload.length);(messageLength bytes)(payload bytes)
            var headerBuff = data.subarray(pos + 2, pos + 2 + endOfLengthHeader);
            var headerString = String.fromCharCode.apply(null, new Uint8Array(headerBuff)); //data.toString('utf8', pos+2, endOfLengthHeader);
            var messageLength = 0;
            var payloadLength = 0;
            if (headerString.indexOf('|') > 0) {
                var arr = headerString.split('|');
                messageLength = parseInt(arr[0]);
                payloadLength = parseInt(arr[1]);
            }
            else {
                messageLength = parseInt(headerString);
            }
            // 一个完整的包的长度 最后的2 是\r\n
            var packageLength = endOfLengthHeader + 1 + messageLength + payloadLength + 2;
            if (total < packageLength) { // 收到的包不完整, 退出
                console.log('package not ready, received:' + total + ' total: ' + packageLength);
                this.buffer = data.subarray(pos, total);
                break;
            }
            // 解析消息结构体
            if (messageLength > 0) {
                var slice = data.subarray(endOfLengthHeader + 1, endOfLengthHeader + 1 + messageLength);
                var sliceStr = this.Utf8ArrayToStr(slice); //String.fromCharCode.apply(null, new Uint8Array(slice));
                console.log('receive message string:' + sliceStr);
                var msg = Message.fromJSON(JSON.parse(sliceStr));
                if (payloadLength > 0) {
                    var imgSlice = data.subarray(endOfLengthHeader + 1 + messageLength, endOfLengthHeader + 1 + messageLength + payloadLength);
                    console.log('received payload length:' + imgSlice.length);
                    msg.binary = imgSlice;
                }
                messages.push(msg);
            }
            pos += packageLength;
            this.buffer = null;
        }
        return messages;
    },
    parseSend: function (json) {
        var payload = JSON.stringify(json);
        var data = 'L:' + payload.length + ';' + payload + "\r\n";
        var buffer = new ArrayBuffer(data.length);
        var bufView = new Uint8Array(buffer);
        for (var i = 0; i < data.length; i++) {
            bufView[i] = data.charCodeAt(i);
        }
        return buffer;
    },
};
