/*eslint-disable*/

import Emiter from 'Emiter';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
import everSocket from 'everSocket';
import pdu from 'pdus/index';
import PduType from 'pdus/PduType';
import PduConsts from 'pdus/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';
import EngineUtils from 'EngineUtils';

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));
    this._everSocket.on(everSocket.CLOSED, this._everSocketCloseHandler.bind(this));
  }

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

  // EverSocket建立通道完毕
  _everSocketOpenHandler() {
    this._sendJoinClassRequest();
  }
  // EverSocket连接断开
  _everSocketCloseHandler() {
    GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
    this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_SOCKET_DISCONNECT);
  }


  //MCU-发送加入会议请求
  _sendJoinClassRequest(){
    //const classInfo = this.classInfo;
    loger.log('MCU-发送加入会议请求.');
    console.log(this.classInfo);
    var descriptorPdu = new pdu['RCConferenceDescriptorPdu'];
    descriptorPdu.id = this.classInfo.classId;
    descriptorPdu.name = this.classInfo.className||"";
    descriptorPdu.mode = 0;
    descriptorPdu.capacity = 1;

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

    let pduMsg = pdu.create_join_class_request_pdu(
        joinRequestPdu.type,
        this.classInfo.nodeId,
        this.classInfo.classId,
        0,
        ApeConsts.BROADCAST_CHANNEL_ID,
        true,
        PduConsts.DP_TOP,
        this.classInfo.topNodeID,
        PduConsts.SEG_ONCE
    );

    pduMsg.set("site", this.classInfo.siteId);//课堂号对应的名称
    pduMsg.set("userId", this.classInfo.userId);
    pduMsg.set("userName", Base64.fromByteArray(ArrayBufferUtil.strToUint8Array(this.classInfo.userName)));
    pduMsg.set("userRole", this.classInfo.userRole);
    pduMsg.set("deviceType",""+GlobalConfig.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.data('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId);
    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.result;
        loger.warn( 'RCPDU_CONNECT_PROVIDER_RESPONSE  ->pduResultCode:'+pduResultCode);
        switch (pduResultCode) {
          case PduConsts.RET_SUCCESS:
              //加入成功
            this._updateMCUConfInfoDescription(joinConfPdu.classDescription);
            this._emit(MessageTypes.CLASS_JOIN_SUCCESS, this.classInfo);
            break;
          case PduConsts.RET_FULL_CAPACITY:
            this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FULL);
            //this._emit(MessageTypes.CLASS_JOIN_FAILED,MessageTypes.ERR_CLASS_JOIN_FULL);
            //this._emit(MessageTypes.CLASS_JOIN_FULL);
            break;
          default:
              loger.arn('JoinConfPdu-未知类型-等待处理.', pduResultCode);
              break
        }
      break;
    case PduType.RCPDU_SEND_DATA_REQUEST:
        //先判断当前消息属于哪个APE 根据 sessionId来判断
      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);
        //ape广播事件,只要ape中监听就能收到
        ape._emit(pduMsg.subType, pduMsg.data);
      } else {
        loger.warn(sessionLabel + '尚未注册');
      }
      break;
    default:
      loger.warn('PDU-未知类型-等待处理.', pduType);
    }
  }

  _updateMCUConfInfoDescription(_data) {
   // let _mcuConfDesc=new pdu['RCConferenceDescriptorPdu'].decode(mcuConfDesc);
    loger.log('_updateMCUConfInfoDescription.');
    //let classDescription=new pdu['RCConferenceDescriptorPdu'].decode(_data);
    console.log(_data);
    //let info = this.mcuClassInfo.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-发送会议数据....');
      this._everSocket.send(msg.toArrayBuffer());
    } else {
      loger.log('MCU-发送会议数据失败,MCU底层通道不可用');
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_SOCKET_DISCONNECT);
    }
  }

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

  // 主动建立MCU连接
  joinMCU(_classInfo) {
    loger.log('开始建立EverSocket通道.');
    console.log(_classInfo);
    _classInfo.classId = parseInt(_classInfo.classId); // classId 必须整形
    this.classInfo = _classInfo;
    // 创建刷新nodeId
    this.classInfo.nodeId =EngineUtils.creatSoleNumberFromTimestamp();
    GlobalConfig.nodeId=this.classInfo.nodeId;//这是标识自己身份的id

    let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
    nodeInfoRecordPdu.name = this.classInfo.userName;
    nodeInfoRecordPdu.nodeId = this.classInfo.nodeId;
    nodeInfoRecordPdu.userId = this.classInfo.userId;
    //nodeInfoRecordPdu.role = 1; //NR_NORMAL
    nodeInfoRecordPdu.role = ApeConsts.userTypesToId[this.classInfo.userRole]||1; //NR_NORMAL用户的身份,根据用户登录时的身份设置
    nodeInfoRecordPdu.level = 0;

    let conferenceRecord = {}; //RCConferenceRecord_T
    conferenceRecord._conference_id = this.classInfo.classId;
    conferenceRecord._top_node_id =this.classInfo.topNodeID;

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

    // 内部mcuConfInfo
    this.classInfo.mcuClassInfo = this.mcuClassInfo;

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

export default new MCU;