/*eslint-disable*/

import Emiter from 'Emiter';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
import everSocket from 'everSocket';
import pdu from 'pdu/index';
import PduType from 'pdu/PduType';
import PduConsts from 'pdu/PduConsts';
import ApeConsts from 'apes/ApeConsts';
import ConferApe from 'apes/ConferApe';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import Base64 from 'base64-js';
//import GlobalConfig from 'GlobalConfig';

let loger = Loger.getLoger('MCU');

class MCU extends Emiter {
  constructor() {
    super();
    this._apes = {};
    this._everSocket = everSocket;
    this._everSocket.on(everSocket.OPEN, this._everSocketOpenHandler.bind(this));
    this._everSocket.on(everSocket.MESSAGE, this._everSocketMsgReceivedHandler.bind(this));
  }

  // 注册Ape
  registerApe(ape) {
    this._apes[ape._session_id] = ape;
  }

  // EverSocket建立通道完毕
  _everSocketOpenHandler() {
    this._sendJoinClassRequest();
  }

  //MCU-发送加入会议请求
  _sendJoinClassRequest(){
    loger.log('MCU-发送加入会议请求.');
    const confInfo = this.confInfo;

    // 创建刷新nodeId
    confInfo.nodeId = parseInt(Date.now() / 1000);

    var joinRequestPdu = new pdu['RCConferenceJoinRequestPdu'];
    joinRequestPdu.type = 2;
    joinRequestPdu.initiator = confInfo.nodeId;
    joinRequestPdu.nodeType = PduConsts.NT_TERMINAL; //normal

    var descriptorPdu = new pdu['RCConferenceDescriptorPdu'];
    descriptorPdu.id = confInfo.confId;
    descriptorPdu.name = new ArrayBuffer;
    descriptorPdu.mode = 0;
    descriptorPdu.capacity = 1;
    joinRequestPdu.confDesc = descriptorPdu;

    let pduMsg = pdu.create_connect_provider_request_pdu(
        joinRequestPdu.type,
        confInfo.nodeId,
        confInfo.confId,
        0,
        ApeConsts.BROADCAST_CHANNEL_ID,
        true,
        PduConsts.DP_TOP,
        confInfo.topNodeID,
        PduConsts.SEG_ONCE
    );

    pduMsg.set("site", confInfo.siteId);
    pduMsg.set("userId", confInfo.userId);
    pduMsg.set("userName", Base64.fromByteArray(ArrayBufferUtil.strToUint8Array(confInfo.userName)));
    pduMsg.set("userRole", confInfo.userRole);
    pduMsg.set("deviceType", "");
    pduMsg.set("data", joinRequestPdu.toArrayBuffer());

    this._everSocket.send(pduMsg.toArrayBuffer());
  }

  // EverSocket底层消息处理
  _everSocketMsgReceivedHandler(data) {
    let pduMsg = pdu.decode_pdu(data);
    let pduType = pduMsg.get("type");
    let pduData = pduMsg.get("data");
    loger.log('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId);
    switch (pduType) {
      case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE:
          //加入会议请求返回数据处理
        let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData);
        let pduResultCode = joinConfPdu.get("result");
        switch (pduResultCode) {
          case PduConsts.RET_SUCCESS:
              //加入成功
            this._updateMCUConfInfoDesc(joinConfPdu.get("confDesc"));
            this._emit(MessageTypes.CLASS_JOIN_SUCCESS, this.confInfo);
            break;
          case PduConsts.RET_FULL_CAPACITY:
            this._emit(MessageTypes.CLASS_JOIN_FAILED,MessageTypes.ERROR_CLASS_JOIN_FULL);
            //this._emit(MessageTypes.CLASS_JOIN_FULL);
            break;
          default:
              loger.arn('JoinConfPdu-未知类型-等待处理.', pduResultCode);
              break
        }
      break;
    case PduType.RCPDU_SEND_DATA_REQUEST:
      let ape = this._apes[pduMsg.sessionId];
      let sessionLabel = ApeConsts(pduMsg.sessionId);
      if (ape) {
        let subTypeLabel = pdu.id2type(pduMsg.subType);
        loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType);
        loger.log("ape._emit("+pduMsg.subType+", "+pduMsg.data+")---------------------------");
        ape._emit(pduMsg.subType, pduMsg.data);
      } else {
        loger.warn(sessionLabel + '尚未注册');
      }
      break;
    default:
      loger.warn('PDU-未知类型-等待处理.', pduType);
    }
  }

  _updateMCUConfInfoDesc(mcuConfDesc) {
    let info = this.mcuConfInfo.info;
    info._conference_name = ArrayBufferUtil.uint8ArrayToStr(mcuConfDesc.name, 0);
    info._capacity = mcuConfDesc.capacity;
    info._mode = mcuConfDesc.mode;
  }

  // MU服务是否连接
  get connected() {
    if (this._everSocket && this._everSocket.connected)
      return true;
    return false;
  }

  // 会议发送消息 -- 消息同意序列号
  send(msg) {
    if (this.connected) {
      loger.log('MCU-发送会议数据....', msg);
      this._everSocket.send(msg.toArrayBuffer());
    } else {
      loger.log('MCU-发送会议数据失败,MCU底层通道不可用');
    }
  }

  // 主动断开MCU连接
  leaveMCU() {
    // for (let ape in this._apes) {
    //   this._apes[ape].stop();
    // }
    this._everSocket.end();
  }

  // 主动建立MCU连接
  joinMCU(_confInfo) {
    loger.log('开始建立EverSocket通道.', _confInfo);
    _confInfo.confId = parseInt(_confInfo.confId); // confId 必须整形
    this.confInfo = _confInfo;

    let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
    nodeInfoRecordPdu.name = this.confInfo.userName;
    nodeInfoRecordPdu.nodeId = this.confInfo.nodeId;
    nodeInfoRecordPdu.userId = this.confInfo.userId;
    nodeInfoRecordPdu.role = 1; //NR_NORMAL
    nodeInfoRecordPdu.level = 0;

    let conferenceRecord = {}; //RCConferenceRecord_T
    conferenceRecord._conference_id = this.confInfo.confId;
    conferenceRecord._top_node_id =this.confInfo.topNodeID;

    this.mcuConfInfo = {}; //RCMeetingInfo_T
    this.mcuConfInfo.self = nodeInfoRecordPdu;
    this.mcuConfInfo.info = conferenceRecord;

    // 内部mcuConfInfo
    this.confInfo.mcuConfInfo = this.mcuConfInfo;

    //开启EverSocket
    this._everSocket.begin(this.confInfo.MCUServerIP,this.confInfo.MCUServerPort);
  }
}

export default new MCU;