/*
 * Author: 众产®  https://ciy.cn/code
 * Version: 0.1.1
 */
'use strict';
ciyclass.websocket = function (addr, header) {
    var thos = this;
    this.buffer = new Array(); //发送数据缓冲区
    this.reOpenData = [2, 5, 3, 5, 5, 3, 5, 8, 10, 20, 30, 30]; //断线重连，每次间隔时间/秒
    this.reOpen = 0; //断线重连次数
    this.wsidx = 0;
    this.keepAliveTimer = setInterval(function () {
        try {
            if (thos.wsock && thos.wsock.readyState !== 1) {
                thos.reOpenSec--;
                if (thos.reOpenSec <= 0) {
                    thos.reOpen++;
                    thos.reOpenSec = 10;
                    thos.open();
                }
                return;
            }
            if (thos.buffer.length > 0) {
                var data = thos.buffer.pop();
                thos.send(data);
            } else {
                if (new Date().getTime() - thos.last_health_time >= 15000 && thos.wsock.readyState === 1) {
                    console.log('ping');
                    thos.wsock.send('h');//.ping();
                    thos.last_health_time = new Date().getTime();
                }
            }
        } catch (err) {
            console.log(err);
        }
    }, 1000);
    this.setOpenSec = function () {
        (thos.reOpen < thos.reOpenData.length) ? thos.reOpenSec = thos.reOpenData[thos.reOpen] : thos.reOpenSec = 90; //断线重试太多后的间隔时间
    }
    this.open = function () {
        try {
            if (thos.wsock && thos.wsock.trueClose)
                return;
            thos.setOpenSec();
            if (thos.wsock) {
                if (thos.wsock.readyState == 1)
                    return;
                thos.wsock.close();
            }
            thos.wsock = new WebSocket(addr);
            thos.wsock.onopen = function (event) {
                try {
                    //获取header，刷新reauth
                    thos.reOpen = 0;
                    thos.last_health_time = new Date().getTime();
                    if (typeof (thos.onopen) == "function")
                        thos.onopen(event);
                } catch (err) {
                    console.log('ws.onopen', err);
                }
            };
            thos.wsock.onmessage = function (e) {
                try {
                    thos.last_health_time = new Date().getTime();
                    if (typeof (thos.onmessage) == "function")
                        thos.onmessage(e);
                } catch (err) {
                    console.log('ws.onmessage', err);
                }
            };
            thos.wsock.onclose = function (e) {
                try {
                    if (this.trueClose) {
                        clearInterval(thos.keepAliveTimer);
                        return;
                    }
                    thos.setOpenSec();
                    if (typeof (thos.onclose) == "function")
                        thos.onclose(e);
                } catch (err) {
                    console.log('ws.onclose', err);
                }
            };
            thos.wsock.onerror = function (e) {
                try {
                    thos.setOpenSec();
                    if (typeof (thos.onerror) == "function")
                        thos.onerror(e);
                } catch (err) {
                    console.log('ws.onerror', err);
                }
            };
        } catch (err) {
            console.log('ws.open', err);
        }
    }
    this.send = function (msg) {
        console.log('op send', msg);
        try {
            if (this.wsock === undefined || this.wsock.trueClose)
                return false;
            if (this.wsock.readyState !== 1 || this.wsock.bufferedAmount > 0)
                this.buffer.push(msg);
            else {
                this.wsock.send(msg);
                this.last_health_time = new Date().getTime();
            }
            return true;
        } catch (err) {
            console.log('ws.send', err);
        }
    }
    this.sendjson = function (json) {
        console.log('op sendjson', json);
        json._wsidx = this.wsidx++;
        try {
            if (this.wsock === undefined || this.wsock.trueClose)
                return false;
            if (this.wsock.readyState !== 1 || this.wsock.bufferedAmount > 0)
                this.buffer.push(JSON.stringify(json));
            else {
                this.wsock.send(JSON.stringify(json));
                this.last_health_time = new Date().getTime();
            }
            return true;
        } catch (err) {
            console.log('ws.sendjson', err);
        }
    }
    this.close = function (send) {
        this.wsock.trueClose = true;
        this.wsock.close();
    }
    this.open();
}
ciyfn.bin2hex = function (str) {
    var ret = '';
    for (var i = 0, l = str.length; i < l; i++) {
        var c = str.charCodeAt(i).toString(16);
        if (c.length == 1)
            c = '0' + c;
        ret += c;
    }
    return ret;
}
ciyfn.hex2bin = function (str) {
    var ret = '';
    for (var i = 0; i < str.length - 1; i += 2) {
        ret += String.fromCharCode(parseInt(str.substr(i, 2), 16));
    }
    return ret;
}