import global from '../common/global';
import baseUtil from '../utils/base';

const CONNECTING = 0;
const OPEN = 1;
const CLOSING = 2;
const CLOSED = 3;
const CLOSE_NORMAL = 1000;

/**
 * 长链接管理器
 */
class WebSocketManager {

  constructor(opt) {
    // 默认常量
    this.CONNECTING = CONNECTING;
    this.OPEN = OPEN;
    this.CLOSING = CLOSING;
    this.CLOSED = CLOSED;

    opt = typeof opt === 'string' ? { url: opt } : (opt || {});
    const { adapter } = global.platform || {};
    const { socket } = adapter || {};
    this._socket = socket ? new socket(opt) : {};
    this.readyState = 0;

    this.onopen = () => { };
    this.onclose = () => { };
    this.onerror = () => { };
    this.onmessage = () => { };

    // 初始化监听 建立链接
    this._socket.onopen = (...args) => {
      this.readyState = OPEN;
      baseUtil.isFun(this.onopen) && this.onopen(...args);
    };

    // 初始化监听 收到消息
    this._socket.onmessage = (...args) => {
      baseUtil.isFun(this.onmessage) && this.onmessage(...args);
    };

    // 初始化监听 报错
    this._socket.onerror = (err) => {
      this.readyState = CLOSED;
      baseUtil.isFun(this.onerror) && this.onerror(err);
    };

    // 初始化监听 断开链接
    this._socket.onclose = (...args) => {
      this.readyState = CLOSED;
      baseUtil.isFun(this.onclose) && this.onclose(...args);
    };
  }

  /**
   * 发送长链接消息
   * @param {any} data 
   */
  send(data) {
    try {
      if (this.readyState === CONNECTING) {
        throw new Error("INVALID_STATE_ERROR");
      }
      this._socket.send(data);
    } catch (err) {
      this._socket.onerror(err);
    }
  }

  /**
   * 长链接断开
   * @param {number} code 
   * @param {string} reason 
   */
  close(code, reason) {
    try {
      if (this.readyState !== CLOSING && this.readyState !== CLOSED) {
        this.readyState = CLOSING;
        this._socket.close(baseUtil.toNumber(code, CLOSE_NORMAL), baseUtil.toStr(reason));
      }
    } catch (err) {
      this._socket.onerror(err);
    }
  }

  /**
   * 长链接实例销毁
   */
  destroy() {
    this.onopen = () => { };
    this.onclose = () => { };
    this.onerror = () => { };
    this.onmessage = () => { };
    this._socket.destroy();
  }
}

/** 连接中，常量 */
WebSocketManager.CONNECTING = CONNECTING;
/** 已连接，常量 */
WebSocketManager.OPEN = OPEN;
/** 断开中，常量 */
WebSocketManager.CLOSING = CLOSING;
/** 已断开，常量 */
WebSocketManager.CLOSED = CLOSED;

export default WebSocketManager;