import _regeneratorRuntime from 'babel-runtime/regenerator';
import _getIterator from 'babel-runtime/core-js/get-iterator';
import _Promise from 'babel-runtime/core-js/promise';
import _slicedToArray from 'babel-runtime/helpers/slicedToArray';
import _asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _ from 'lodash';

import * as arbitratorConstants from '../constants/arbitrator';
import * as notificationConstants from '../constants/notification';
import * as disputeConstants from '../constants/dispute';
import { MISSING_STORE_PROVIDER } from '../constants/error';
import isRequired from '../utils/isRequired';

/**
 * Notifications API. Use this object to fetch notifications from the store, register
 * event log handlers to update store and send push notifications.
 */

var Notifications = function Notifications() {
  var arbitratorInstance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : isRequired('arbitratorInstance');
  var arbitrableInstance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : isRequired('arbitrableInstance');
  var storeProviderInstance = arguments[2];

  _classCallCheck(this, Notifications);

  _initialiseProps.call(this);

  this._ArbitratorInstance = arbitratorInstance;
  this._ArbitrableInstance = arbitrableInstance;
  this._StoreProviderInstance = storeProviderInstance;
}
/**
 * Set arbitrator instance.
 * @param {object} arbitratorInstance - instance of an arbitrator contract.
 */

/**
 * Set arbitrable instance.
 * @param {object} arbitrableInstance - instance of an arbitrable contract.
 */

/**
 * Set store provider instance.
 * @param {object} storeProviderInstance - instance of store provider wrapper.
 */


// **************************** //
// *         Public           * //
// **************************** //

/**
 * Register event handlers for the arbitrator instance.
 * @param {string} account - Filter notifications for account.
 * @param {object} eventListener - Event Listener that will fetch logs and call callbacks
 * @param {function} callback - If we want notifications to be "pushed" provide a callback function to call when a new notification is created.
 */


/**
 * Get stateful notifications. Stateful notifications change based on the state of the arbitrator contract.
 * @param {string} account - Filter notifications for account.
 * @param {function} isJuror - If the account is a juror.
 * @returns {object[]} - Array of stateful notification objects.
 */


/**
 * Fetch all unread notifications from store.
 * @param {string} account - Address of user.
 * @returns {object[]} - Array of notification objects.
 */


/**
 * Mark stored notification as read.
 * @param {string} account address of user
 * @param {string} txHash hash of transaction that produced event
 * @param {number} logIndex index of the log. used to differentiate logs if multiple logs per tx
 * @returns {promise} promise that can be waited on for syncronousity
 */


/**
 * Fetch all user notifications from store.
 * @param {string} account - Address of user.
 * @returns {object[]} - Array of notification objects.
 */


// **************************** //
// *        Handlers          * //
// **************************** //

/**
 * Checks for appeal possible notifications during APPEAL period.
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


/**
 * Handler for DisputeCreation event
 * sends notification to partyA and partyB when dispute is created
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


/**
 * handler for AppealPossible event
 * sends notification informing accounts that a ruling has been made and an appeal possible
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


/**
 * Handler for AppealDecision event
 * sends notification informing subscribers that a ruling has been appealed
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


/**
 * Handler for TokenShift event.
 * NOTE: you will get a notification for each vote. So a juror that has 3 votes will receive 3 notifications
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


/**
 * Handler for arbitration reward event.
 * @param {object} event - The event log.
 * @param {string} account - The user account.
 * @param {function} callback - The callback.
 */


// **************************** //
// *        Helpers           * //
// **************************** //
/**
 * Helper method to create handler with correct params
 * @param {function} handler - The handler.
 * @param {string} account - The account.
 * @param {function} callback - The callback.
 * @returns {object} - The created handler.
 */


/**
 * Sends a push notification.
 * @param {function} callback - The callback.
 * @param {object} notification - The notification.
 */


/**
 * Creates a notification object.
 * @param {number} notificationType - The notificationType.
 * @param {string} message - The message.
 * @param {object} data - The data.
 * @returns {function} - The notification object.
 */


/**
 * Creates a new notification object in the store.
 * @param {string} account - The account.
 * @param {string} txHash - The txHash.
 * @param {string} blockNumber - The block number of the event log.
 * @param {number} logIndex - The logIndex.
 * @param {number} notificationType - The notificationType.
 * @param {string} message - The message.
 * @param {object} data - The data.
 * @param {bool} read - Wether the notification has been read or not.
 * @returns {function} - The notification object.
 */


/**
 * Get contracts from store if set or return empty array. Used for notifications
 * @param {string} account - Filter notifications for account.
 * @returns {object[]} - Array of dispute objects
 */


/**
 * Get disputes either from store or from arbitrator if Store Provider is not set. Used for notifications
 * @param {string} account - Filter notifications for account.
 * @param {function} isJuror - If the account is a juror.
 * @returns {object[]} - Array of dispute objects
 */
;

var _initialiseProps = function _initialiseProps() {
  var _this = this;

  this.setArbitratorInstance = function (arbitratorInstance) {
    _this._ArbitratorInstance = arbitratorInstance;
  };

  this.setArbitrableInstance = function (arbitrableInstance) {
    _this._ArbitrableInstance = arbitrableInstance;
  };

  this.setStoreProviderInstance = function (storeProviderInstance) {
    _this._StoreProviderInstance = storeProviderInstance;
  };

  this.registerArbitratorNotifications = function () {
    var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : isRequired('account');
    var eventListener = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : isRequired('eventListener');
    var callback = arguments[2];

    var eventHandlerMap = {
      DisputeCreation: _this._disputeCreationHandler,
      AppealPossible: _this._appealPossibleHandler,
      AppealDecision: _this._appealingDecisionHandler,
      TokenShift: _this._tokenShiftHandler,
      ArbitrationReward: _this._arbitrationRewardHandler,
      NewPeriod: _this._newPeriodHandler
    };

    for (var event in eventHandlerMap) {
      if (eventHandlerMap.hasOwnProperty(event)) {
        eventListener.addEventHandler(_this._ArbitratorInstance, event, _this._createHandler(eventHandlerMap[event], account, callback));
      }
    }
  };

  this.getStatefulNotifications = function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(account) {
      var isJuror = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

      var notifications, _ref2, _ref3, contracts, disputes, currentPeriod, currentSession, contractInstance, lastActivatedSession, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, dispute, draws, canVote;

      return _regeneratorRuntime.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              notifications = [];
              _context3.next = 3;
              return _Promise.all([_this._getContracts(account), _this._getDisputes(account, isJuror)]);

            case 3:
              _ref2 = _context3.sent;
              _ref3 = _slicedToArray(_ref2, 2);
              contracts = _ref3[0];
              disputes = _ref3[1];
              _context3.next = 9;
              return _this._ArbitratorInstance.getPeriod();

            case 9:
              currentPeriod = _context3.sent;
              _context3.next = 12;
              return _this._ArbitratorInstance.getSession();

            case 12:
              currentSession = _context3.sent;

              if (!isJuror) {
                _context3.next = 57;
                break;
              }

              if (!(currentPeriod === arbitratorConstants.PERIOD.ACTIVATION)) {
                _context3.next = 24;
                break;
              }

              _context3.next = 17;
              return _this._ArbitratorInstance.loadContract();

            case 17:
              contractInstance = _context3.sent;
              _context3.next = 20;
              return contractInstance.jurors(account);

            case 20:
              lastActivatedSession = _context3.sent[2].toNumber();

              if (lastActivatedSession < currentSession) {
                notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_ACTIVATE, 'Ready to deposit tokens', {}));
              }
              _context3.next = 55;
              break;

            case 24:
              if (!(currentPeriod === arbitratorConstants.PERIOD.VOTE)) {
                _context3.next = 55;
                break;
              }

              _iteratorNormalCompletion = true;
              _didIteratorError = false;
              _iteratorError = undefined;
              _context3.prev = 28;
              _iterator = _getIterator(disputes);

            case 30:
              if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
                _context3.next = 41;
                break;
              }

              dispute = _step.value;
              draws = dispute.appealDraws[dispute.appealDraws.length - 1];

              if (!draws) {
                _context3.next = 38;
                break;
              }

              _context3.next = 36;
              return _this._ArbitratorInstance.canRuleDispute(dispute.disputeId, draws, account);

            case 36:
              canVote = _context3.sent;

              if (canVote) {
                notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_VOTE, 'Need to vote on dispute', {
                  disputeId: dispute.disputeId,
                  arbitratorAddress: dispute.arbitratorAddress
                }));
              }

            case 38:
              _iteratorNormalCompletion = true;
              _context3.next = 30;
              break;

            case 41:
              _context3.next = 47;
              break;

            case 43:
              _context3.prev = 43;
              _context3.t0 = _context3['catch'](28);
              _didIteratorError = true;
              _iteratorError = _context3.t0;

            case 47:
              _context3.prev = 47;
              _context3.prev = 48;

              if (!_iteratorNormalCompletion && _iterator.return) {
                _iterator.return();
              }

            case 50:
              _context3.prev = 50;

              if (!_didIteratorError) {
                _context3.next = 53;
                break;
              }

              throw _iteratorError;

            case 53:
              return _context3.finish(50);

            case 54:
              return _context3.finish(47);

            case 55:
              _context3.next = 59;
              break;

            case 57:
              _context3.next = 59;
              return _Promise.all(contracts.map(function () {
                var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(contract) {
                  var contractData, arbitrationCost;
                  return _regeneratorRuntime.wrap(function _callee$(_context) {
                    while (1) {
                      switch (_context.prev = _context.next) {
                        case 0:
                          _context.next = 2;
                          return _this._ArbitrableInstance.setContractInstance(contract.address);

                        case 2:
                          _context.next = 4;
                          return _this._ArbitrableInstance.getData(contract.partyA);

                        case 4:
                          contractData = _context.sent;
                          _context.next = 7;
                          return _this._ArbitratorInstance.getArbitrationCost(contractData.arbitratorExtraData);

                        case 7:
                          arbitrationCost = _context.sent;

                          if (contractData.partyA === account) {
                            if (contractData.partyAFee < arbitrationCost) {
                              notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_PAY_FEE, 'Arbitration fee required', {
                                arbitratorAddress: contractData.arbitrator,
                                arbitrableContractAddress: contract.address,
                                feeToPay: arbitrationCost - contractData.partyAFee
                              }));
                            }
                          } else if (contractData.partyB === account) {
                            if (contractData.partyBFee < arbitrationCost) {
                              notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_PAY_FEE, 'Arbitration fee required', {
                                arbitratorAddress: contractData.arbitrator,
                                arbitrableContractAddress: contract.address,
                                feeToPay: arbitrationCost - contractData.partyBFee
                              }));
                            }
                          }

                        case 9:
                        case 'end':
                          return _context.stop();
                      }
                    }
                  }, _callee, _this);
                }));

                return function (_x7) {
                  return _ref4.apply(this, arguments);
                };
              }()));

            case 59:
              if (!(currentPeriod === arbitratorConstants.PERIOD.EXECUTE)) {
                _context3.next = 62;
                break;
              }

              _context3.next = 62;
              return _Promise.all(disputes.map(function () {
                var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(dispute) {
                  var disputeData;
                  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
                    while (1) {
                      switch (_context2.prev = _context2.next) {
                        case 0:
                          _context2.next = 2;
                          return _this._ArbitratorInstance.getDispute(dispute.disputeId);

                        case 2:
                          disputeData = _context2.sent;

                          if (disputeData.firstSession + disputeData.numberOfAppeals === currentSession) {
                            if (disputeData.state <= disputeConstants.STATE.RESOLVING) {
                              notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_REPARTITION, 'Ready to repartition dispute', {
                                disputeId: dispute.disputeId,
                                arbitratorAddress: dispute.arbitratorAddress
                              }));
                            } else if (disputeData.state === disputeConstants.STATE.EXECUTABLE) {
                              notifications.push(_this._createNotification(notificationConstants.TYPE.CAN_EXECUTE, 'Ready to execute dispute', {
                                disputeId: dispute.disputeId,
                                arbitratorAddress: dispute.arbitratorAddress
                              }));
                            }
                          }

                        case 4:
                        case 'end':
                          return _context2.stop();
                      }
                    }
                  }, _callee2, _this);
                }));

                return function (_x8) {
                  return _ref5.apply(this, arguments);
                };
              }()));

            case 62:
              return _context3.abrupt('return', notifications);

            case 63:
            case 'end':
              return _context3.stop();
          }
        }
      }, _callee3, _this, [[28, 43, 47, 55], [48,, 50, 54]]);
    }));

    return function (_x5) {
      return _ref.apply(this, arguments);
    };
  }();

  this.getUnreadStoredNotifications = function () {
    var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(account) {
      var profile, currentArbitrator;
      return _regeneratorRuntime.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _this._requireStoreProvider();
              _context4.next = 3;
              return _this._StoreProviderInstance.newUserProfile(account);

            case 3:
              profile = _context4.sent;
              currentArbitrator = _this._ArbitratorInstance.getContractAddress();
              // return notifications that are for current arbitrator and are unread

              return _context4.abrupt('return', _.filter(profile.notifications, function (notification) {
                return notification.data.arbitratorAddress === currentArbitrator && !notification.read;
              }));

            case 6:
            case 'end':
              return _context4.stop();
          }
        }
      }, _callee4, _this);
    }));

    return function (_x9) {
      return _ref6.apply(this, arguments);
    };
  }();

  this.markStoredNotificationAsRead = function () {
    var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(account, txHash, logIndex) {
      var result;
      return _regeneratorRuntime.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              _this._requireStoreProvider();
              _context5.next = 3;
              return _this._StoreProviderInstance.markNotificationAsRead(account, txHash, logIndex, true);

            case 3:
              result = _context5.sent;
              return _context5.abrupt('return', result);

            case 5:
            case 'end':
              return _context5.stop();
          }
        }
      }, _callee5, _this);
    }));

    return function (_x10, _x11, _x12) {
      return _ref7.apply(this, arguments);
    };
  }();

  this.getStoredNotifications = function () {
    var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(account) {
      return _regeneratorRuntime.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              _this._requireStoreProvider();

              _context6.next = 3;
              return _this._StoreProviderInstance.getUserProfile(account);

            case 3:
              return _context6.abrupt('return', _context6.sent.notifications);

            case 4:
            case 'end':
              return _context6.stop();
          }
        }
      }, _callee6, _this);
    }));

    return function (_x13) {
      return _ref8.apply(this, arguments);
    };
  }();

  this._newPeriodHandler = function () {
    var _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(event, account, callback) {
      var newPeriod, eventSession, currentSession, disputes, openDisputes, arbitratorAddress;
      return _regeneratorRuntime.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              newPeriod = event.args._period.toNumber();
              eventSession = event.args._session.toNumber();
              _context8.next = 4;
              return _this._ArbitratorInstance.getSession();

            case 4:
              currentSession = _context8.sent;

              if (!(newPeriod === arbitratorConstants.PERIOD.APPEAL && eventSession === currentSession)) {
                _context8.next = 15;
                break;
              }

              _context8.next = 8;
              return _this._getDisputes(account);

            case 8:
              disputes = _context8.sent;
              _context8.next = 11;
              return _this._ArbitratorInstance.getOpenDisputesForSession();

            case 11:
              openDisputes = _context8.sent;
              // get all disputes for session
              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();
              _context8.next = 15;
              return _Promise.all(openDisputes.map(function () {
                var _ref10 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(openDispute) {
                  var ruling, notification;
                  return _regeneratorRuntime.wrap(function _callee7$(_context7) {
                    while (1) {
                      switch (_context7.prev = _context7.next) {
                        case 0:
                          if (!(_.findIndex(disputes, function (dispute) {
                            return dispute.disputeId === openDispute.disputeId && dispute.arbitratorAddress === arbitratorAddress;
                          }) >= 0)) {
                            _context7.next = 9;
                            break;
                          }

                          _context7.next = 3;
                          return _this._ArbitratorInstance.currentRulingForDispute(openDispute.disputeId, openDispute.numberOfAppeals);

                        case 3:
                          ruling = _context7.sent;
                          _context7.next = 6;
                          return _this._newNotification(account, event.transactionHash, event.blockNumber, openDispute.disputeId, // use disputeId instead of logIndex since it doens't have its own event
                          notificationConstants.TYPE.APPEAL_POSSIBLE, 'A ruling has been made. Appeal is possible', {
                            disputeId: openDispute.disputeId,
                            arbitratorAddress: arbitratorAddress,
                            ruling: ruling
                          });

                        case 6:
                          notification = _context7.sent;
                          _context7.next = 9;
                          return _this._sendPushNotification(callback, notification);

                        case 9:
                        case 'end':
                          return _context7.stop();
                      }
                    }
                  }, _callee7, _this);
                }));

                return function (_x17) {
                  return _ref10.apply(this, arguments);
                };
              }()));

            case 15:
            case 'end':
              return _context8.stop();
          }
        }
      }, _callee8, _this);
    }));

    return function (_x14, _x15, _x16) {
      return _ref9.apply(this, arguments);
    };
  }();

  this._disputeCreationHandler = function () {
    var _ref11 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(event, account, callback) {
      var disputeId, txHash, arbitrableData, arbitratorAddress, notification;
      return _regeneratorRuntime.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              disputeId = event.args._disputeID.toNumber();
              txHash = event.transactionHash;
              // load arbitrable contract

              _context9.next = 4;
              return _this._ArbitrableInstance.setContractInstance(event.args._arbitrable);

            case 4:
              _context9.next = 6;
              return _this._ArbitrableInstance.getData();

            case 6:
              arbitrableData = _context9.sent;

              if (!(arbitrableData.partyA === account || arbitrableData.partyB === account)) {
                _context9.next = 15;
                break;
              }

              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();
              _context9.next = 11;
              return _this._newNotification(account, txHash, event.blockNumber, event.logIndex, notificationConstants.TYPE.DISPUTE_CREATED, 'New Dispute Created', {
                disputeId: disputeId,
                arbitratorAddress: arbitratorAddress
              });

            case 11:
              notification = _context9.sent;

              if (!notification) {
                _context9.next = 15;
                break;
              }

              _context9.next = 15;
              return _this._sendPushNotification(callback, notification);

            case 15:
            case 'end':
              return _context9.stop();
          }
        }
      }, _callee9, _this);
    }));

    return function (_x18, _x19, _x20) {
      return _ref11.apply(this, arguments);
    };
  }();

  this._appealPossibleHandler = function () {
    var _ref12 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10(event, account, callback) {
      var disputes, disputeId, ruling, arbitratorAddress, notification;
      return _regeneratorRuntime.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              _context10.next = 2;
              return _this._getDisputes(account);

            case 2:
              disputes = _context10.sent;
              disputeId = event.args._disputeID.toNumber();
              _context10.next = 6;
              return _this._ArbitratorInstance.currentRulingForDispute(disputeId);

            case 6:
              ruling = _context10.sent;
              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();

              if (!(_.findIndex(disputes, function (dispute) {
                return dispute.disputeId === disputeId && dispute.arbitratorAddress === arbitratorAddress;
              }) >= 0)) {
                _context10.next = 15;
                break;
              }

              _context10.next = 11;
              return _this._newNotification(account, event.transactionHash, event.blockNumber, event.logIndex, notificationConstants.TYPE.APPEAL_POSSIBLE, 'A ruling has been made. Appeal is possible', {
                disputeId: disputeId,
                arbitratorAddress: arbitratorAddress,
                ruling: ruling
              });

            case 11:
              notification = _context10.sent;

              if (!notification) {
                _context10.next = 15;
                break;
              }

              _context10.next = 15;
              return _this._sendPushNotification(callback, notification);

            case 15:
            case 'end':
              return _context10.stop();
          }
        }
      }, _callee10, _this);
    }));

    return function (_x21, _x22, _x23) {
      return _ref12.apply(this, arguments);
    };
  }();

  this._appealingDecisionHandler = function () {
    var _ref13 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11(event, account, callback) {
      var disputes, disputeId, arbitratorAddress, notification;
      return _regeneratorRuntime.wrap(function _callee11$(_context11) {
        while (1) {
          switch (_context11.prev = _context11.next) {
            case 0:
              _context11.next = 2;
              return _this._getDisputes(account);

            case 2:
              disputes = _context11.sent;
              disputeId = event.args._disputeID.toNumber();
              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();

              if (!(_.findIndex(disputes, function (dispute) {
                return dispute.disputeId === disputeId && dispute.arbitratorAddress === arbitratorAddress;
              }) >= 0)) {
                _context11.next = 12;
                break;
              }

              _context11.next = 8;
              return _this._newNotification(account, event.transactionHash, event.blockNumber, event.logIndex, notificationConstants.TYPE.RULING_APPEALED, 'A ruling been appealed', {
                disputeId: disputeId,
                arbitratorAddress: arbitratorAddress
              });

            case 8:
              notification = _context11.sent;

              if (!notification) {
                _context11.next = 12;
                break;
              }

              _context11.next = 12;
              return _this._sendPushNotification(callback, notification);

            case 12:
            case 'end':
              return _context11.stop();
          }
        }
      }, _callee11, _this);
    }));

    return function (_x24, _x25, _x26) {
      return _ref13.apply(this, arguments);
    };
  }();

  this._tokenShiftHandler = function () {
    var _ref14 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12(event, account, callback) {
      var disputeId, address, amount, arbitratorAddress, notification;
      return _regeneratorRuntime.wrap(function _callee12$(_context12) {
        while (1) {
          switch (_context12.prev = _context12.next) {
            case 0:
              // address indexed _account, uint _disputeID, int _amount
              disputeId = event.args._disputeID.toNumber();
              address = event.args._account;
              amount = event.args._amount.toNumber();

              if (!(account === address)) {
                _context12.next = 11;
                break;
              }

              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();
              _context12.next = 7;
              return _this._newNotification(account, event.transactionHash, event.blockNumber, event.logIndex, notificationConstants.TYPE.TOKEN_SHIFT, 'Tokens have been redistributed', {
                disputeId: disputeId,
                arbitratorAddress: arbitratorAddress,
                account: address,
                amount: amount
              });

            case 7:
              notification = _context12.sent;

              if (!notification) {
                _context12.next = 11;
                break;
              }

              _context12.next = 11;
              return _this._sendPushNotification(callback, notification);

            case 11:
            case 'end':
              return _context12.stop();
          }
        }
      }, _callee12, _this);
    }));

    return function (_x27, _x28, _x29) {
      return _ref14.apply(this, arguments);
    };
  }();

  this._arbitrationRewardHandler = function () {
    var _ref15 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13(event, account, callback) {
      var disputeId, address, amount, arbitratorAddress, notification;
      return _regeneratorRuntime.wrap(function _callee13$(_context13) {
        while (1) {
          switch (_context13.prev = _context13.next) {
            case 0:
              // address indexed _account, uint _disputeID, int _amount
              disputeId = event.args._disputeID.toNumber();
              address = event.args._account;
              amount = event.args._amount.toNumber();

              if (!(account === address)) {
                _context13.next = 11;
                break;
              }

              arbitratorAddress = _this._ArbitratorInstance.getContractAddress();
              _context13.next = 7;
              return _this._newNotification(account, event.transactionHash, event.blockNumber, event.logIndex, notificationConstants.TYPE.ARBITRATION_REWARD, 'Juror awarded arbitration fee', {
                disputeId: disputeId,
                arbitratorAddress: arbitratorAddress,
                account: address,
                amount: amount
              });

            case 7:
              notification = _context13.sent;

              if (!notification) {
                _context13.next = 11;
                break;
              }

              _context13.next = 11;
              return _this._sendPushNotification(callback, notification);

            case 11:
            case 'end':
              return _context13.stop();
          }
        }
      }, _callee13, _this);
    }));

    return function (_x30, _x31, _x32) {
      return _ref15.apply(this, arguments);
    };
  }();

  this._createHandler = function (handler, account, callback) {
    return function (args) {
      return handler(args, account, callback);
    };
  };

  this._sendPushNotification = function () {
    var _ref16 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee14(callback, notification) {
      return _regeneratorRuntime.wrap(function _callee14$(_context14) {
        while (1) {
          switch (_context14.prev = _context14.next) {
            case 0:
              if (callback && notification) {
                callback(notification);
              }

            case 1:
            case 'end':
              return _context14.stop();
          }
        }
      }, _callee14, _this);
    }));

    return function (_x33, _x34) {
      return _ref16.apply(this, arguments);
    };
  }();

  this._createNotification = function (notificationType, message, data) {
    return {
      notificationType: notificationType,
      message: message,
      data: data
    };
  };

  this._newNotification = function () {
    var _ref17 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15(account, txHash, blockNumber, logIndex, notificationType) {
      var message = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : '';
      var data = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
      var read = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
      var response, notification;
      return _regeneratorRuntime.wrap(function _callee15$(_context15) {
        while (1) {
          switch (_context15.prev = _context15.next) {
            case 0:
              if (!_this._StoreProviderInstance) {
                _context15.next = 11;
                break;
              }

              _context15.next = 3;
              return _this._StoreProviderInstance.updateLastBlock(account, blockNumber);

            case 3:
              _context15.next = 5;
              return _this._StoreProviderInstance.newNotification(account, txHash, logIndex, notificationType, message, data, read);

            case 5:
              response = _context15.sent;

              if (!(response.status === 201)) {
                _context15.next = 9;
                break;
              }

              notification = response.body.notifications.filter(function (notification) {
                return notification.txHash === txHash && notification.logIndex === logIndex;
              });
              return _context15.abrupt('return', notification[0]);

            case 9:
              _context15.next = 12;
              break;

            case 11:
              return _context15.abrupt('return', {
                txHash: txHash,
                logIndex: logIndex,
                notificationType: notificationType,
                message: message,
                data: data,
                read: read
              });

            case 12:
            case 'end':
              return _context15.stop();
          }
        }
      }, _callee15, _this);
    }));

    return function (_x35, _x36, _x37, _x38, _x39) {
      return _ref17.apply(this, arguments);
    };
  }();

  this._getContracts = function () {
    var _ref18 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16(account) {
      var contracts, userProfile;
      return _regeneratorRuntime.wrap(function _callee16$(_context16) {
        while (1) {
          switch (_context16.prev = _context16.next) {
            case 0:
              contracts = [];

              // If we have store provider fetch contracts and disputes from the store.

              if (!_this._StoreProviderInstance) {
                _context16.next = 6;
                break;
              }

              _context16.next = 4;
              return _this._StoreProviderInstance.newUserProfile(account);

            case 4:
              userProfile = _context16.sent;


              contracts = userProfile.contracts;

            case 6:
              return _context16.abrupt('return', contracts);

            case 7:
            case 'end':
              return _context16.stop();
          }
        }
      }, _callee16, _this);
    }));

    return function (_x43) {
      return _ref18.apply(this, arguments);
    };
  }();

  this._getDisputes = function () {
    var _ref19 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17(account) {
      var isJuror = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var disputes;
      return _regeneratorRuntime.wrap(function _callee17$(_context17) {
        while (1) {
          switch (_context17.prev = _context17.next) {
            case 0:
              disputes = [];

              // If we have store provider fetch contracts and disputes from the store.

              if (!_this._StoreProviderInstance) {
                _context17.next = 7;
                break;
              }

              _context17.next = 4;
              return _this._StoreProviderInstance.getDisputes(account);

            case 4:
              disputes = _context17.sent;
              _context17.next = 11;
              break;

            case 7:
              if (!isJuror) {
                _context17.next = 11;
                break;
              }

              _context17.next = 10;
              return _this._ArbitratorInstance.getDisputesForJuror(account);

            case 10:
              disputes = _context17.sent;

            case 11:
              return _context17.abrupt('return', disputes);

            case 12:
            case 'end':
              return _context17.stop();
          }
        }
      }, _callee17, _this);
    }));

    return function (_x44) {
      return _ref19.apply(this, arguments);
    };
  }();

  this._requireStoreProvider = function () {
    if (!_this._StoreProviderInstance) throw new Error(MISSING_STORE_PROVIDER);
  };
};

export default Notifications;
//# sourceMappingURL=Notifications.js.map