"use strict";

var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
  value: true
});
exports.getCallManager = exports.CallManager = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
var _request = require("../utils/request");
var _constants = require("../../common/constants");
var _constants2 = require("../constants");
var _types = require("../../Events/types");
var _impl = require("../../Events/impl");
var _SDKConnector = _interopRequireDefault(require("../../SDKConnector"));
var _types2 = require("../../common/types");
var _types3 = require("./types");
var _call4 = require("./call");
var _Logger = _interopRequireDefault(require("../../Logger"));
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable dot-notation */ /* eslint-disable valid-jsdoc */
var callManager;

/**
 *
 */
var CallManager = exports.CallManager = /*#__PURE__*/function (_Eventing) {
  /**
   * @param webex -.
   * @param indicator - Service Indicator.
   */
  function CallManager(webex, indicator) {
    var _this;
    (0, _classCallCheck2.default)(this, CallManager);
    _this = _callSuper(this, CallManager);
    (0, _defineProperty2.default)(_this, "sdkConnector", void 0);
    (0, _defineProperty2.default)(_this, "webex", void 0);
    (0, _defineProperty2.default)(_this, "callCollection", void 0);
    (0, _defineProperty2.default)(_this, "activeMobiusUrl", void 0);
    (0, _defineProperty2.default)(_this, "serviceIndicator", void 0);
    (0, _defineProperty2.default)(_this, "lineDict", void 0);
    (0, _defineProperty2.default)(_this, "apiRequest", void 0);
    /**
     * @param direction -.
     * @param deviceId -.
     * @param destination -.
     */
    (0, _defineProperty2.default)(_this, "createCall", function (direction, deviceId, lineId, destination) {
      _Logger.default.info("".concat(_constants.METHOD_START_MESSAGE, " with ").concat(direction, ", ").concat(deviceId, " and ").concat(lineId), {
        file: _constants2.CALL_MANAGER_FILE,
        method: _constants2.METHODS.CREATE_CALL
      });
      _Logger.default.log('Creating call object', {});
      var newCall = (0, _call4.createCall)(_this.activeMobiusUrl, _this.webex, direction, deviceId, lineId, function (correlationId) {
        delete _this.callCollection[correlationId];
        var activeCalls = (0, _keys.default)(_this.getActiveCalls()).length;
        _Logger.default.info("DELETE:: Deleted corelationId: ".concat(newCall.getCorrelationId(), " from CallManager, Number of call records :- ").concat(activeCalls), {});
        if (activeCalls === 0) {
          /* Notify CallingClient when all calls are cleared. */
          _this.emit(_types.CALLING_CLIENT_EVENT_KEYS.ALL_CALLS_CLEARED);
          _Logger.default.log('All calls have been cleared', {
            file: _constants2.CALL_MANAGER_FILE,
            method: _constants2.METHODS.CREATE_CALL
          });
        }
      }, _this.serviceIndicator, destination);
      _this.callCollection[newCall.getCorrelationId()] = newCall;
      _Logger.default.log("New call created with correlationId: ".concat(newCall.getCorrelationId()), {});
      _Logger.default.info("ADD:: Added corelationId: ".concat(newCall.getCorrelationId(), " to CallManager , Number of call records now:- ").concat((0, _keys.default)(_this.getActiveCalls()).length), {});
      return newCall;
    });
    /**
     * @param correlationId -.
     */
    (0, _defineProperty2.default)(_this, "getCall", function (correlationId) {
      return _this.callCollection[correlationId];
    });
    /**
     *
     */
    (0, _defineProperty2.default)(_this, "getActiveCalls", function () {
      return _this.callCollection;
    });
    _this.sdkConnector = _SDKConnector.default;
    _this.serviceIndicator = indicator;
    if (!_this.sdkConnector.getWebex()) {
      _SDKConnector.default.setWebex(webex);
    }
    _this.lineDict = {};
    _this.webex = _this.sdkConnector.getWebex();
    _this.apiRequest = _request.APIRequest.getInstance({
      webex: _this.webex
    });
    _this.callCollection = {};
    _this.activeMobiusUrl = '';
    _this.listenForWsEvents();
    return _this;
  }
  (0, _inherits2.default)(CallManager, _Eventing);
  return (0, _createClass2.default)(CallManager, [{
    key: "updateActiveMobius",
    value:
    /**
     * Update Active Mobius Url.
     *
     * @param url - Mobius Url.
     */
    function updateActiveMobius(url) {
      this.activeMobiusUrl = url;
      _Logger.default.log("Successfully updated active Mobius URL to: ".concat(url), {
        file: _constants2.CALL_MANAGER_FILE,
        method: _constants2.METHODS.UPDATE_ACTIVE_MOBIUS
      });
    }

    /**
     * A listener for Mobius events.
     */
  }, {
    key: "listenForWsEvents",
    value: function listenForWsEvents() {
      var _this2 = this;
      if (!this.apiRequest.isSocketEnabled()) {
        this.sdkConnector.registerListener('event:mobius', /*#__PURE__*/function () {
          var _ref = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(event) {
            return _regenerator.default.wrap(function (_context) {
              while (1) switch (_context.prev = _context.next) {
                case 0:
                  _this2.dequeueWsEvents(event);
                case 1:
                case "end":
                  return _context.stop();
              }
            }, _callee);
          }));
          return function (_x) {
            return _ref.apply(this, arguments);
          };
        }());
        _Logger.default.info('Successfully registered listener for Mobius events', {
          file: _constants2.CALL_MANAGER_FILE,
          method: _constants2.METHODS.REGISTER_SESSIONS_LISTENER
        });
      }
    }

    /**
     * This a Queue where Mobius Events are reported by the underlying Mercury
     * Connection. We handle the events in the order they are posted here. New call
     * Objects are generated from here.
     *
     * @param event - Mobius Events.
     */
  }, {
    key: "dequeueWsEvents",
    value: function dequeueWsEvents(event) {
      var _this3 = this;
      _Logger.default.info("".concat(_constants.METHOD_START_MESSAGE, " with event ").concat(event), {
        file: _constants2.CALL_MANAGER_FILE,
        method: _constants2.METHODS.DEQUEUE_WS_EVENTS
      });
      var mobiusEvent = event;
      var _ref2 = mobiusEvent.data,
        callId = _ref2.callId,
        correlationId = _ref2.correlationId;
      switch (mobiusEvent.data.eventType) {
        case _types3.MobiusEventType.CALL_SETUP:
          {
            _Logger.default.log("Received call Setup message for call: ".concat(callId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            /* Check whether MidCall or not */
            if (mobiusEvent.data.midCallService) {
              mobiusEvent.data.midCallService.forEach(function (midCallEvent) {
                var call = _this3.getCall(correlationId);
                if (call) {
                  call.handleMidCallEvent(midCallEvent);
                } else {
                  _Logger.default.info("Dropping midcall event of type: ".concat(midCallEvent.eventType, " as it doesn't match with any existing call"), {
                    file: _constants2.CALL_MANAGER_FILE,
                    method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                  });
                }
              });
              return;
            }
            /* Check if the Call.Media was processed before Call.Setup.
             * In that case , the Call Object is already created while processing
             * Media message.
             */

            var newId = (0, _keys.default)(this.callCollection).find(function (id) {
              return _this3.callCollection[id].getCallId() === callId;
            });
            var newCall;
            if (!newId) {
              /*  This means it's a new call ...
               *  Create an incoming call object and add to our records
               */
              var lineId = this.getLineId(mobiusEvent.data.deviceId);
              newCall = this.createCall(_types2.CallDirection.INBOUND, mobiusEvent.data.deviceId, lineId, {});
              _Logger.default.log("New incoming call created with correlationId from Call Setup message: ".concat(newCall.getCorrelationId()), {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              newCall.setCallId(callId);
              if (mobiusEvent.data.broadworksCorrelationInfo) {
                _Logger.default.info("Found broadworksCorrelationInfo: ".concat(mobiusEvent.data.broadworksCorrelationInfo), {
                  file: _constants2.CALL_MANAGER_FILE,
                  method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                });
                newCall.setBroadworksCorrelationInfo(mobiusEvent.data.broadworksCorrelationInfo);
              }
            } else {
              _Logger.default.info("Found the call Object with a matching callId: ".concat(callId, " from our records with correlationId: ").concat(newId), {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              newCall = this.getCall(newId);
            }
            if (mobiusEvent.data.callerId) {
              _Logger.default.info('Processing Caller-Id data', {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              newCall.startCallerIdResolution(mobiusEvent.data.callerId);
            }
            /* Signal Line */

            this.emit(_types.LINE_EVENT_KEYS.INCOMING_CALL, newCall);
            newCall.sendCallStateMachineEvt({
              type: 'E_RECV_CALL_SETUP',
              data: mobiusEvent.data
            });
            break;
          }
        case _types3.MobiusEventType.CALL_PROGRESS:
          {
            _Logger.default.log("Received call progress mobiusEvent for call: ".concat(correlationId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            var call = this.getCall(correlationId);
            if (mobiusEvent.data.callerId) {
              _Logger.default.info('Processing Caller-Id data', {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              call.startCallerIdResolution(mobiusEvent.data.callerId);
            }
            call.sendCallStateMachineEvt({
              type: 'E_RECV_CALL_PROGRESS',
              data: mobiusEvent.data
            });
            break;
          }
        case _types3.MobiusEventType.CALL_INFO:
          {
            _Logger.default.log("Received call info mobiusEvent for call: ".concat(correlationId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            var _call = this.getCall(correlationId);
            if (_call && mobiusEvent.data.callerId) {
              _Logger.default.info('Processing Caller-Id data', {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              _call.startCallerIdResolution(mobiusEvent.data.callerId);
            }
            break;
          }
        case _types3.MobiusEventType.CALL_MEDIA:
          {
            _Logger.default.log("Received call media mobiusEvent for call: ".concat(correlationId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            var activeCall;
            if (correlationId) {
              /* The Call.Media message had correlation id (Except the first message) */
              activeCall = this.getCall(correlationId);
            } else {
              /* This is possibly the first Media message for the call.
               * We should scan our record to see if we can find a call with
               * this callId.
               */

              var _newId = (0, _keys.default)(this.callCollection).find(function (id) {
                return _this3.callCollection[id].getCallId() === callId;
              });
              if (_newId) {
                /* Call.Media arrived after Call.Setup but the correlationId was Null. */

                _Logger.default.info("Found the call Object with a matching callId: ".concat(callId, " from our records with correlationId: ").concat(_newId), {
                  file: _constants2.CALL_MANAGER_FILE,
                  method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                });
                activeCall = this.getCall(_newId);
              } else {
                /* If Call.Media arrived before Call.Setup , we create the Call Object here */

                var _lineId = this.getLineId(mobiusEvent.data.deviceId);
                activeCall = this.createCall(_types2.CallDirection.INBOUND, mobiusEvent.data.deviceId, _lineId, {});
                _Logger.default.log("New incoming call created with correlationId from ROAP Message: ".concat(activeCall.getCorrelationId()), {
                  file: _constants2.CALL_MANAGER_FILE,
                  method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                });
                activeCall.setCallId(callId);
              }
            }
            if (activeCall) {
              var _mobiusEvent$data$mes, _mobiusEvent$data$mes2, _mobiusEvent$data$mes3, _mobiusEvent$data$mes4, _mobiusEvent$data$mes5;
              /* Only Handle if the call is present */

              _Logger.default.info("SDP from mobius ".concat((_mobiusEvent$data$mes = mobiusEvent.data.message) === null || _mobiusEvent$data$mes === void 0 ? void 0 : _mobiusEvent$data$mes.sdp), {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              _Logger.default.log("ROAP message from mobius with type:  ".concat((_mobiusEvent$data$mes2 = mobiusEvent.data.message) === null || _mobiusEvent$data$mes2 === void 0 ? void 0 : _mobiusEvent$data$mes2.messageType, ", seq: ").concat((_mobiusEvent$data$mes3 = mobiusEvent.data.message) === null || _mobiusEvent$data$mes3 === void 0 ? void 0 : _mobiusEvent$data$mes3.seq, " , version: ").concat((_mobiusEvent$data$mes4 = mobiusEvent.data.message) === null || _mobiusEvent$data$mes4 === void 0 ? void 0 : _mobiusEvent$data$mes4.version), {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              var mediaState = (_mobiusEvent$data$mes5 = mobiusEvent.data.message) === null || _mobiusEvent$data$mes5 === void 0 ? void 0 : _mobiusEvent$data$mes5.messageType;
              switch (mediaState) {
                case _types3.MediaState.OFFER:
                  {
                    _Logger.default.log('Received OFFER', {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                    activeCall.sendMediaStateMachineEvt({
                      type: 'E_RECV_ROAP_OFFER',
                      data: mobiusEvent.data.message
                    });
                    break;
                  }
                case _types3.MediaState.ANSWER:
                  {
                    _Logger.default.log('Received ANSWER', {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                    activeCall.sendMediaStateMachineEvt({
                      type: 'E_RECV_ROAP_ANSWER',
                      data: mobiusEvent.data.message
                    });
                    break;
                  }
                case _types3.MediaState.OFFER_REQUEST:
                  {
                    _Logger.default.log('Received OFFER_REQUEST', {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                    activeCall.sendMediaStateMachineEvt({
                      type: 'E_RECV_ROAP_OFFER_REQUEST',
                      data: mobiusEvent.data.message
                    });
                    break;
                  }
                case _types3.MediaState.OK:
                  {
                    _Logger.default.log('Received OK', {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                    var mediaOk = {
                      received: true,
                      message: mobiusEvent.data.message
                    };
                    activeCall.sendMediaStateMachineEvt({
                      type: 'E_ROAP_OK',
                      data: mediaOk
                    });
                    break;
                  }
                case _types3.MediaState.ERROR:
                  {
                    _Logger.default.log('Received Error...', {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                    break;
                  }
                default:
                  {
                    _Logger.default.log("Unknown Media mobiusEvent: ".concat(mediaState, " "), {
                      file: _constants2.CALL_MANAGER_FILE,
                      method: _constants2.METHODS.DEQUEUE_WS_EVENTS
                    });
                  }
              }
            } else {
              _Logger.default.info("CorrelationId: ".concat(correlationId, " doesn't exist , discarding.."), {
                file: _constants2.CALL_MANAGER_FILE,
                method: _constants2.METHODS.DEQUEUE_WS_EVENTS
              });
              // TODO: Maybe add a queue  for these mobiusEvents per callID and handle them once the call is setup ?
            }
            break;
          }
        case _types3.MobiusEventType.CALL_CONNECTED:
          {
            _Logger.default.log("Received call connect for call: ".concat(correlationId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            var _call2 = this.getCall(correlationId);
            _call2.sendCallStateMachineEvt({
              type: 'E_RECV_CALL_CONNECT',
              data: mobiusEvent.data
            });
            break;
          }
        case _types3.MobiusEventType.CALL_DISCONNECTED:
          {
            _Logger.default.log("Received call disconnect for call: ".concat(correlationId), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
            var _call3 = this.getCall(correlationId);
            if (_call3) {
              _call3.sendCallStateMachineEvt({
                type: 'E_RECV_CALL_DISCONNECT'
              });
            }
            break;
          }
        default:
          {
            _Logger.default.log("Unknown Call Event mobiusEvent: ".concat(mobiusEvent.data.eventType), {
              file: _constants2.CALL_MANAGER_FILE,
              method: _constants2.METHODS.DEQUEUE_WS_EVENTS
            });
          }
      }
    }
  }, {
    key: "updateLine",
    value:
    /**
     * Adds line instance to lineDict
     */
    function updateLine(deviceId, line) {
      this.lineDict[deviceId] = line;
      _Logger.default.log("Successfully updated line for deviceId: ".concat(deviceId), {
        file: _constants2.CALL_MANAGER_FILE,
        method: _constants2.METHODS.UPDATE_LINE
      });
    }

    /**
     * Retrieves line id
     */
  }, {
    key: "getLineId",
    value: function getLineId(deviceId) {
      return this.lineDict[deviceId].lineId;
    }
  }]);
}(_impl.Eventing);
/**
 * @param webex -.
 * @param indicator - Service Indicator.
 */
var getCallManager = exports.getCallManager = function getCallManager(webex, indicator) {
  if (!callManager) {
    callManager = new CallManager(webex, indicator);
  }
  return callManager;
};
//# sourceMappingURL=callManager.js.map
