'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');

var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _Kleros = require('kleros/build/contracts/Kleros');

var _Kleros2 = _interopRequireDefault(_Kleros);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _MiniMePinakion = require('../PNK/MiniMePinakion');

var _MiniMePinakion2 = _interopRequireDefault(_MiniMePinakion);

var _eth = require('../../../constants/eth');

var ethConstants = _interopRequireWildcard(_eth);

var _error = require('../../../constants/error');

var errorConstants = _interopRequireWildcard(_error);

var _arbitrator = require('../../../constants/arbitrator');

var arbitratorConstants = _interopRequireWildcard(_arbitrator);

var _ContractImplementation = require('../../ContractImplementation');

var _ContractImplementation2 = _interopRequireDefault(_ContractImplementation);

var _deployContractAsync = require('../../../utils/deployContractAsync');

var _deployContractAsync2 = _interopRequireDefault(_deployContractAsync);

var _EventListener = require('../../../utils/EventListener');

var _EventListener2 = _interopRequireDefault(_EventListener);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Provides interaction with a Kleros contract on the blockchain.
 */
var Kleros = function (_ContractImplementati) {
  (0, _inherits3.default)(Kleros, _ContractImplementati);

  /**
   * Create new Kleros Implementation.
   * @param {object} web3Provider - web3 instance.
   * @param {string} contractAddress - Address of the Kleros contract.
   */
  function Kleros(web3Provider, contractAddress) {
    var artifact = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Kleros2.default;
    (0, _classCallCheck3.default)(this, Kleros);

    var _this = (0, _possibleConstructorReturn3.default)(this, (Kleros.__proto__ || (0, _getPrototypeOf2.default)(Kleros)).call(this, web3Provider, artifact, contractAddress));

    _initialiseProps.call(_this);

    return _this;
  }

  /**
   * STATIC: Deploy a Kleros contract on the blockchain.
   * @param {string} rngAddress address of random number generator contract
   * @param {string} pnkAddress address of pinakion contract
   * @param {number[]} timesPerPeriod array of 5 ints indicating the time limit for each period of contract
   * @param {string} account address of user
   * @param {number} value amout of eth to send to contract
   * @param {object} web3Provider web3 provider object NOTE: NOT Kleros Web3Wrapper
   * @returns {object} truffle-contract Object | err The contract object or error deploy
   */


  /**
   * Deposit PNK to the contract.
   * @param {number} amount - The amount of PNK to deposit.
   * @param {string} account - The address of the user.
   * @returns {object} - Balance information including total PNK balance and activated tokens.
   */


  /**
   * Withdraw PNK from the contract.
   * @param {number} amount - The amount of PNK to deposit.
   * @param {string} account - The address of the user.
   * @returns {object} - Balance information including total PNK balance and activated tokens.
   */


  /**
   * Get PNK Balances.
   * @param {string} account - The address of the user.
   * @returns {object} - Balance information including total PNK balance and activated tokens.
   */


  /**
   * Activate Pinakion tokens to be eligible to be a juror.
   * @param {string} amount - number of tokens to activate.
   * @param {string} account - address of user.
   * @returns {object} - PNK balance.
   */


  /**
   * Fetch the cost of arbitration.
   * @param {bytes} contractExtraData - extra data from arbitrable contract.
   * @returns {number} - The cost of arbitration.
   */


  /**
   * Fetch the cost of appeal.
   * @param {number} disputeId - index of the dispute.
   * @param {bytes} contractExtraData - extra data from arbitrable contract.
   * @returns {number} - The cost of appeal.
   */


  /**
   * Call contract to move on to the next period.
   * @param {string} account - address of user.
   * @returns {Promise} - resulting object.
   */


  /**
   * Submit votes. Note can only be called during Voting period (Period 2).
   * @param {number} disputeId - index of the dispute.
   * @param {number} ruling - int representing the jurors decision.
   * @param {number[]} votes - int[] of drawn votes for dispute.
   * @param {string} account - address of user.
   * @returns {object} - The result transaction object.
   */


  /**
   * Appeal ruling on dispute.
   * @param {number} disputeId - Index of the dispute.
   * @param {string} extraData - Extra data.
   * @param {string} account - Address of user.
   * @returns {object} - The result transaction object.
   */


  /**
   * Repartition juror tokens.
   * @param {number} disputeId - index of the dispute.
   * @param {string} account - address of user.
   * @returns {object} - The result transaction object.
   */


  /**
   * Execute ruling on dispute
   * @param {number} disputeId - index of the dispute.
   * @param {string} account - address of user.
   * @returns {object} - The result transaction object.
   */


  /**
   * Get time for a period.
   * @param {number} periodNumber - int representing period.
   * @returns {number} - The seconds in the period.
   */


  /**
   * Get dispute.
   * @param {number} disputeId - The index of the dispute.
   * @returns {object} - The dispute data from the contract.
   */


  /**
   * Get number of jurors for a dispute.
   * @param {number} disputeId - Index of dispute.
   * @returns {number} - Number of jurors for a dispute.
   */


  /**
   * Get number of jurors for a dispute.
   * @param {number} disputeId - Index of dispute.
   * @param {number} draw - Int for draw.
   * @param {string} jurorAddress - Address of juror.
   * @returns {bool} - `true` indicates juror has a vote for draw, `false` indicates they do not.
   */


  /**
   * Can juror currently rule in dispute.
   * @param {number} disputeId - index of dispute.
   * @param {int[]} draws - voting positions for dispute.
   * @param {string} account - address of user.
   * @returns {bool} - Boolean indicating if juror can rule or not.
   */


  /**
   * Get number of jurors for a dispute.
   * @param {number} disputeId - Index of dispute.
   * @param {number} appeal - Index of appeal.
   * @returns {number} - Int indicating the ruling of the dispute.
   */


  /**
   * Get current period of the contract
   * @returns {number} - Int indicating the period.
   */


  /**
   * Get current session of the contract.
   * @returns {number} - Int indicating the session.
   */


  /**
   * Get disputes from Kleros contract.
   * @param {string} account - Address of user.
   * @returns {object[]} - Array of disputes.
   */


  /**
   * Fetch the votes a juror has in a dispute.
   * @param {number} disputeId - ID of the dispute.
   * @param {string} account - Potential jurors address.
   * @returns {number[]} - Array of integers indicating the draw.
   */


  /** Get all disputes that are active this session.
   * @returns {int[]} - array of active disputeId
   */


  /**
   * Find when a ruling was made in a session
   * @param {number} session - The session number.
   * @returns {number[]} an array of timestamps
   */


  /**
   * Find the deadline for disputes in a session.
   * @param {number} session - The session number.
   * @returns {number[]} an array of timestamps
   */


  /**
   * Get the event log for an appeal creation
   * @param {number} session - The session number.
   * @returns {number[]} an array of timestamps
   */


  /**
   * Get the event log for the dispute creation.
   * @param {number} disputeId - The block number that the dispute was created.
   * @returns {object} dispute creation event log.
   */


  /**
   * Get the amount of tokens won or lost by a juror for a dispute
   * @param {number} disputeId The index of the dispute
   * @param {string} account The account of the juror
   * @returns {number} The net total PNK
   */


  /**
   * Get the timestamp from blockNumber
   * @param {number} blockNumber - The block number
   * @returns {number} timestamp
   */


  /**
   * Get event NewPeriod event logs a period in a session.
   * @param {number} session - The session number.
   * @param {number} periodNumber - The period number we want logs for.
   * @returns {object} event log object.
   */


  /**
   * Get data from Kleros contract.
   * TODO split these into their own methods for more flexability and speed
   * @returns {object} - Data for kleros POC from contract.
   */


  return Kleros;
}(_ContractImplementation2.default);

Kleros.deploy = function () {
  var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(rngAddress, pnkAddress) {
    var timesPerPeriod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [300, 0, 300, 300, 300];
    var account = arguments[3];
    var value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ethConstants.TRANSACTION.VALUE;
    var web3Provider = arguments[5];
    var contractDeployed;
    return _regenerator2.default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return (0, _deployContractAsync2.default)(account, value, _Kleros2.default, web3Provider, pnkAddress, rngAddress, timesPerPeriod);

          case 2:
            contractDeployed = _context.sent;
            return _context.abrupt('return', contractDeployed);

          case 4:
          case 'end':
            return _context.stop();
        }
      }
    }, _callee, undefined);
  }));

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

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

  this.transferPNKToArbitrator = function () {
    var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(amount) {
      var account = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this2._Web3Wrapper.getAccount(0);
      var pinakionContractAddress, pnkInstance, deposited;
      return _regenerator2.default.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return _this2.loadContract();

            case 2:
              _context2.next = 4;
              return _this2.contractInstance.pinakion();

            case 4:
              pinakionContractAddress = _context2.sent;
              pnkInstance = new _MiniMePinakion2.default(_this2.getWeb3Provider(), pinakionContractAddress);
              _context2.next = 8;
              return pnkInstance.approveAndCall(_this2.contractAddress, amount, account);

            case 8:
              deposited = _context2.sent;

              if (deposited) {
                _context2.next = 11;
                break;
              }

              throw new Error('Unable to deposit PNK');

            case 11:
              return _context2.abrupt('return', _this2.getPNKBalance(account));

            case 12:
            case 'end':
              return _context2.stop();
          }
        }
      }, _callee2, _this2);
    }));

    return function (_x6) {
      return _ref2.apply(this, arguments);
    };
  }();

  this.withdrawPNK = function () {
    var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(amount) {
      var account = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return _this2.loadContract();

            case 2:
              _context3.next = 4;
              return _this2.contractInstance.withdraw(_this2._Web3Wrapper.toWei(amount, 'ether'), {
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              });

            case 4:
              return _context3.abrupt('return', _this2.getPNKBalance(account));

            case 5:
            case 'end':
              return _context3.stop();
          }
        }
      }, _callee3, _this2);
    }));

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

  this.getPNKBalance = function () {
    var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      var juror, totalTokens, currentSession, activatedTokens, lockedTokens;
      return _regenerator2.default.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return _this2.loadContract();

            case 2:
              _context4.next = 4;
              return _this2.contractInstance.jurors(account);

            case 4:
              juror = _context4.sent;

              if (juror) {
                _context4.next = 7;
                break;
              }

              throw new Error(errorConstants.ACCOUNT_NOT_A_JUROR_FOR_CONTRACT(account, _this2.contractAddress));

            case 7:

              // Total tokens
              totalTokens = _this2._Web3Wrapper.fromWei(juror[0], 'ether');

              // Activated Tokens

              _context4.next = 10;
              return _this2.contractInstance.session();

            case 10:
              currentSession = _context4.sent;
              activatedTokens = 0;

              if (juror[2].toNumber() === currentSession.toNumber()) activatedTokens = _this2._Web3Wrapper.fromWei(juror[4].toNumber() - juror[3].toNumber(), 'ether');

              // Locked Tokens
              lockedTokens = _this2._Web3Wrapper.fromWei(juror[1], 'ether');
              return _context4.abrupt('return', {
                tokenBalance: totalTokens,
                activatedTokens: activatedTokens,
                lockedTokens: lockedTokens
              });

            case 15:
            case 'end':
              return _context4.stop();
          }
        }
      }, _callee4, _this2);
    }));

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

  this.activatePNK = function () {
    var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(amount) {
      var account = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              _context5.next = 2;
              return _this2.loadContract();

            case 2:
              _context5.prev = 2;
              _context5.next = 5;
              return _this2.contractInstance.activateTokens(_this2._Web3Wrapper.toWei(amount, 'ether'), {
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              });

            case 5:
              _context5.next = 11;
              break;

            case 7:
              _context5.prev = 7;
              _context5.t0 = _context5['catch'](2);

              console.error(_context5.t0);
              throw new Error(errorConstants.UNABLE_TO_ACTIVATE_PNK);

            case 11:
              return _context5.abrupt('return', _this2.getPNKBalance(account));

            case 12:
            case 'end':
              return _context5.stop();
          }
        }
      }, _callee5, _this2, [[2, 7]]);
    }));

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

  this.getArbitrationCost = function () {
    var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(contractExtraData) {
      var arbitrationCost;
      return _regenerator2.default.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              _context6.next = 2;
              return _this2.loadContract();

            case 2:
              _context6.prev = 2;
              _context6.next = 5;
              return _this2.contractInstance.arbitrationCost(contractExtraData);

            case 5:
              arbitrationCost = _context6.sent;
              return _context6.abrupt('return', _this2._Web3Wrapper.fromWei(arbitrationCost, 'ether'));

            case 9:
              _context6.prev = 9;
              _context6.t0 = _context6['catch'](2);

              console.error(_context6.t0);
              throw new Error(errorConstants.UNABLE_TO_FETCH_ARBITRATION_COST);

            case 13:
            case 'end':
              return _context6.stop();
          }
        }
      }, _callee6, _this2, [[2, 9]]);
    }));

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

  this.getAppealCost = function () {
    var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(disputeId, contractExtraData) {
      var appealCost;
      return _regenerator2.default.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              _context7.next = 2;
              return _this2.loadContract();

            case 2:
              _context7.prev = 2;
              _context7.next = 5;
              return _this2.contractInstance.appealCost(disputeId, contractExtraData);

            case 5:
              appealCost = _context7.sent;
              return _context7.abrupt('return', _this2._Web3Wrapper.fromWei(appealCost, 'ether'));

            case 9:
              _context7.prev = 9;
              _context7.t0 = _context7['catch'](2);

              console.error(_context7.t0);
              throw new Error(errorConstants.UNABLE_TO_FETCH_APPEAL_COST);

            case 13:
            case 'end':
              return _context7.stop();
          }
        }
      }, _callee7, _this2, [[2, 9]]);
    }));

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

  this.passPeriod = function () {
    var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              _context8.next = 2;
              return _this2.loadContract();

            case 2:
              _context8.prev = 2;
              _context8.next = 5;
              return _this2.contractInstance.passPeriod.original({
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              });

            case 5:
              return _context8.abrupt('return', _this2.getData());

            case 8:
              _context8.prev = 8;
              _context8.t0 = _context8['catch'](2);

              console.error(_context8.t0);
              throw new Error(errorConstants.UNABLE_TO_PASS_PERIOD);

            case 12:
            case 'end':
              return _context8.stop();
          }
        }
      }, _callee8, _this2, [[2, 8]]);
    }));

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

  this.submitVotes = function () {
    var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(disputeId, ruling, votes) {
      var account = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              _context9.next = 2;
              return _this2.loadContract();

            case 2:
              _context9.prev = 2;
              return _context9.abrupt('return', _this2.contractInstance.voteRuling(disputeId, ruling, votes, {
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              }));

            case 6:
              _context9.prev = 6;
              _context9.t0 = _context9['catch'](2);

              console.error(_context9.t0);
              throw new Error(errorConstants.UNABLE_TO_SUBMIT_VOTES);

            case 10:
            case 'end':
              return _context9.stop();
          }
        }
      }, _callee9, _this2, [[2, 6]]);
    }));

    return function (_x17, _x18, _x19) {
      return _ref9.apply(this, arguments);
    };
  }();

  this.appealRuling = function () {
    var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(disputeId, extraData) {
      var account = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              _context10.next = 2;
              return _this2.loadContract();

            case 2:
              _context10.prev = 2;
              _context10.t0 = _this2.contractInstance;
              _context10.t1 = disputeId;
              _context10.t2 = extraData;
              _context10.t3 = account;
              _context10.next = 9;
              return _this2.contractInstance.appealCost(disputeId, extraData);

            case 9:
              _context10.t4 = _context10.sent;
              _context10.t5 = ethConstants.TRANSACTION.GAS;
              _context10.t6 = {
                from: _context10.t3,
                value: _context10.t4,
                gas: _context10.t5
              };
              return _context10.abrupt('return', _context10.t0.appeal.call(_context10.t0, _context10.t1, _context10.t2, _context10.t6));

            case 15:
              _context10.prev = 15;
              _context10.t7 = _context10['catch'](2);

              console.error(_context10.t7);
              throw new Error(errorConstants.UNABLE_TO_APPEAL);

            case 19:
            case 'end':
              return _context10.stop();
          }
        }
      }, _callee10, _this2, [[2, 15]]);
    }));

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

  this.repartitionJurorTokens = function () {
    var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11(disputeId) {
      var account = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee11$(_context11) {
        while (1) {
          switch (_context11.prev = _context11.next) {
            case 0:
              _context11.next = 2;
              return _this2.loadContract();

            case 2:
              _context11.prev = 2;
              return _context11.abrupt('return', _this2.contractInstance.oneShotTokenRepartition(disputeId, {
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              }));

            case 6:
              _context11.prev = 6;
              _context11.t0 = _context11['catch'](2);

              console.error(_context11.t0);
              throw new Error(errorConstants.UNABLE_TO_REPARTITION_TOKENS);

            case 10:
            case 'end':
              return _context11.stop();
          }
        }
      }, _callee11, _this2, [[2, 6]]);
    }));

    return function (_x24) {
      return _ref11.apply(this, arguments);
    };
  }();

  this.executeRuling = function () {
    var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee12(disputeId) {
      var account = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this2._Web3Wrapper.getAccount(0);
      return _regenerator2.default.wrap(function _callee12$(_context12) {
        while (1) {
          switch (_context12.prev = _context12.next) {
            case 0:
              _context12.next = 2;
              return _this2.loadContract();

            case 2:
              _context12.prev = 2;
              return _context12.abrupt('return', _this2.contractInstance.executeRuling(disputeId, {
                from: account,
                gas: ethConstants.TRANSACTION.GAS
              }));

            case 6:
              _context12.prev = 6;
              _context12.t0 = _context12['catch'](2);

              console.error(_context12.t0);
              throw new Error(errorConstants.UNABLE_TO_EXECUTE_RULING);

            case 10:
            case 'end':
              return _context12.stop();
          }
        }
      }, _callee12, _this2, [[2, 6]]);
    }));

    return function (_x26) {
      return _ref12.apply(this, arguments);
    };
  }();

  this.getTimeForPeriod = function () {
    var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee13(periodNumber) {
      var timePerPeriod;
      return _regenerator2.default.wrap(function _callee13$(_context13) {
        while (1) {
          switch (_context13.prev = _context13.next) {
            case 0:
              _context13.next = 2;
              return _this2.loadContract();

            case 2:
              timePerPeriod = void 0;
              _context13.prev = 3;
              _context13.next = 6;
              return _this2.contractInstance.timePerPeriod(periodNumber);

            case 6:
              timePerPeriod = _context13.sent;
              _context13.next = 13;
              break;

            case 9:
              _context13.prev = 9;
              _context13.t0 = _context13['catch'](3);

              console.error(_context13.t0);
              throw new Error(errorConstants.UNABLE_TO_FETCH_TIME_PER_PERIOD);

            case 13:
              if (!timePerPeriod) {
                _context13.next = 15;
                break;
              }

              return _context13.abrupt('return', timePerPeriod.toNumber());

            case 15:
              throw new Error(errorConstants.PERIOD_OUT_OF_RANGE(periodNumber));

            case 16:
            case 'end':
              return _context13.stop();
          }
        }
      }, _callee13, _this2, [[3, 9]]);
    }));

    return function (_x28) {
      return _ref13.apply(this, arguments);
    };
  }();

  this.getDispute = function () {
    var _ref14 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee14(disputeId) {
      var dispute, numberOfAppeals, rulingChoices, voteCounters, status, appeal, voteCounts, choice, _ref15, _ref16;

      return _regenerator2.default.wrap(function _callee14$(_context14) {
        while (1) {
          switch (_context14.prev = _context14.next) {
            case 0:
              _context14.next = 2;
              return _this2.loadContract();

            case 2:
              _context14.prev = 2;
              _context14.next = 5;
              return _this2.contractInstance.disputes(disputeId);

            case 5:
              dispute = _context14.sent;
              numberOfAppeals = dispute[2].toNumber();
              rulingChoices = dispute[3].toNumber();
              voteCounters = [];
              status = void 0;

              for (appeal = 0; appeal <= numberOfAppeals; appeal++) {
                voteCounts = [];

                for (choice = 0; choice <= rulingChoices; choice++) {
                  voteCounts.push(_this2.contractInstance.getVoteCount(disputeId, appeal, choice).then(function (v) {
                    return v.toNumber();
                  }));
                }voteCounters.push(voteCounts);
              }

              ;_context14.next = 14;
              return _promise2.default.all([_promise2.default.all(voteCounters.map(function (voteCounts) {
                return _promise2.default.all(voteCounts);
              })), _this2.contractInstance.disputeStatus(disputeId)]);

            case 14:
              _ref15 = _context14.sent;
              _ref16 = (0, _slicedToArray3.default)(_ref15, 2);
              voteCounters = _ref16[0];
              status = _ref16[1];
              return _context14.abrupt('return', {
                arbitratorAddress: _this2.contractAddress,
                disputeId: disputeId,
                arbitrableContractAddress: dispute[0],
                firstSession: dispute[1].toNumber(),
                numberOfAppeals: numberOfAppeals,
                rulingChoices: rulingChoices,
                initialNumberJurors: dispute[4].toNumber(),
                arbitrationFeePerJuror: _this2._Web3Wrapper.fromWei(dispute[5], 'ether'),
                state: dispute[6].toNumber(),
                voteCounters: voteCounters,
                status: status.toNumber()
                // eslint-disable-next-line no-unused-vars
              });

            case 21:
              _context14.prev = 21;
              _context14.t0 = _context14['catch'](2);
              throw new Error(errorConstants.UNABLE_TO_FETCH_DISPUTE);

            case 24:
            case 'end':
              return _context14.stop();
          }
        }
      }, _callee14, _this2, [[2, 21]]);
    }));

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

  this.getAmountOfJurorsForDispute = function () {
    var _ref17 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee15(disputeId) {
      var amountOfJurors;
      return _regenerator2.default.wrap(function _callee15$(_context15) {
        while (1) {
          switch (_context15.prev = _context15.next) {
            case 0:
              _context15.next = 2;
              return _this2.loadContract();

            case 2:
              amountOfJurors = void 0;
              _context15.prev = 3;
              _context15.next = 6;
              return _this2.contractInstance.amountJurors(disputeId);

            case 6:
              amountOfJurors = _context15.sent;
              _context15.next = 13;
              break;

            case 9:
              _context15.prev = 9;
              _context15.t0 = _context15['catch'](3);

              console.error(_context15.t0);
              throw new Error(errorConstants.UNABLE_TO_FETCH_AMOUNT_OF_JURORS);

            case 13:
              if (!amountOfJurors) {
                _context15.next = 15;
                break;
              }

              return _context15.abrupt('return', amountOfJurors.toNumber());

            case 15:
              throw new Error(errorConstants.DISPUTE_DOES_NOT_EXIST);

            case 16:
            case 'end':
              return _context15.stop();
          }
        }
      }, _callee15, _this2, [[3, 9]]);
    }));

    return function (_x30) {
      return _ref17.apply(this, arguments);
    };
  }();

  this.isJurorDrawnForDispute = function () {
    var _ref18 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee16(disputeId, draw) {
      var jurorAddress = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _this2._Web3Wrapper.getAccount(0);
      var isDrawn;
      return _regenerator2.default.wrap(function _callee16$(_context16) {
        while (1) {
          switch (_context16.prev = _context16.next) {
            case 0:
              _context16.next = 2;
              return _this2.loadContract();

            case 2:
              _context16.next = 4;
              return _this2.contractInstance.isDrawn(disputeId, jurorAddress, draw);

            case 4:
              isDrawn = _context16.sent;
              return _context16.abrupt('return', isDrawn);

            case 6:
            case 'end':
              return _context16.stop();
          }
        }
      }, _callee16, _this2);
    }));

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

  this.canRuleDispute = function () {
    var _ref19 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee17(disputeId, draws, account) {
      var validDraws, lastRuling, currentSession, period;
      return _regenerator2.default.wrap(function _callee17$(_context17) {
        while (1) {
          switch (_context17.prev = _context17.next) {
            case 0:
              _context17.next = 2;
              return _this2.loadContract();

            case 2:
              _context17.next = 4;
              return _this2.contractInstance.validDraws(account, disputeId, draws);

            case 4:
              validDraws = _context17.sent;
              _context17.next = 7;
              return _this2.contractInstance.getLastSessionVote(disputeId, account);

            case 7:
              lastRuling = _context17.sent.toNumber();
              _context17.next = 10;
              return _this2.getSession();

            case 10:
              currentSession = _context17.sent;
              _context17.next = 13;
              return _this2.getPeriod();

            case 13:
              period = _context17.sent;
              return _context17.abrupt('return', validDraws && lastRuling !== currentSession && period < arbitratorConstants.PERIOD.APPEAL);

            case 15:
            case 'end':
              return _context17.stop();
          }
        }
      }, _callee17, _this2);
    }));

    return function (_x34, _x35, _x36) {
      return _ref19.apply(this, arguments);
    };
  }();

  this.currentRulingForDispute = function () {
    var _ref20 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee18(disputeId, appeal) {
      var ruling;
      return _regenerator2.default.wrap(function _callee18$(_context18) {
        while (1) {
          switch (_context18.prev = _context18.next) {
            case 0:
              _context18.next = 2;
              return _this2.loadContract();

            case 2:
              _context18.next = 4;
              return _this2.contractInstance.getWinningChoice(disputeId, appeal);

            case 4:
              ruling = _context18.sent;
              return _context18.abrupt('return', ruling.toNumber());

            case 6:
            case 'end':
              return _context18.stop();
          }
        }
      }, _callee18, _this2);
    }));

    return function (_x37, _x38) {
      return _ref20.apply(this, arguments);
    };
  }();

  this.getPeriod = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee19() {
    var currentPeriod;
    return _regenerator2.default.wrap(function _callee19$(_context19) {
      while (1) {
        switch (_context19.prev = _context19.next) {
          case 0:
            _context19.next = 2;
            return _this2.loadContract();

          case 2:
            _context19.next = 4;
            return _this2.contractInstance.period();

          case 4:
            currentPeriod = _context19.sent;
            return _context19.abrupt('return', currentPeriod.toNumber());

          case 6:
          case 'end':
            return _context19.stop();
        }
      }
    }, _callee19, _this2);
  }));
  this.getSession = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee20() {
    var currentSession;
    return _regenerator2.default.wrap(function _callee20$(_context20) {
      while (1) {
        switch (_context20.prev = _context20.next) {
          case 0:
            _context20.next = 2;
            return _this2.loadContract();

          case 2:
            _context20.next = 4;
            return _this2.contractInstance.session();

          case 4:
            currentSession = _context20.sent;
            return _context20.abrupt('return', currentSession.toNumber());

          case 6:
          case 'end':
            return _context20.stop();
        }
      }
    }, _callee20, _this2);
  }));

  this.getDisputesForJuror = function () {
    var _ref23 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee22(account) {
      var openDisputes, disputes;
      return _regenerator2.default.wrap(function _callee22$(_context22) {
        while (1) {
          switch (_context22.prev = _context22.next) {
            case 0:
              _context22.next = 2;
              return _this2.loadContract();

            case 2:
              _context22.next = 4;
              return _this2.getOpenDisputesForSession();

            case 4:
              openDisputes = _context22.sent;
              _context22.next = 7;
              return _promise2.default.all(openDisputes.map(function () {
                var _ref24 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee21(disputeData) {
                  var draws;
                  return _regenerator2.default.wrap(function _callee21$(_context21) {
                    while (1) {
                      switch (_context21.prev = _context21.next) {
                        case 0:
                          _context21.next = 2;
                          return _this2.getDrawsForJuror(disputeData.disputeId, account);

                        case 2:
                          draws = _context21.sent;

                          disputeData.appealDraws = disputeData.appealDraws || [];
                          disputeData.appealDraws[disputeData.numberOfAppeals] = draws;

                          return _context21.abrupt('return', disputeData);

                        case 6:
                        case 'end':
                          return _context21.stop();
                      }
                    }
                  }, _callee21, _this2);
                }));

                return function (_x40) {
                  return _ref24.apply(this, arguments);
                };
              }()));

            case 7:
              disputes = _context22.sent;
              return _context22.abrupt('return', disputes);

            case 9:
            case 'end':
              return _context22.stop();
          }
        }
      }, _callee22, _this2);
    }));

    return function (_x39) {
      return _ref23.apply(this, arguments);
    };
  }();

  this.getDrawsForJuror = function () {
    var _ref25 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee23(disputeId, account) {
      var numberOfJurors, draws, draw, isJuror;
      return _regenerator2.default.wrap(function _callee23$(_context23) {
        while (1) {
          switch (_context23.prev = _context23.next) {
            case 0:
              _context23.next = 2;
              return _this2.loadContract();

            case 2:
              _context23.next = 4;
              return _this2.getAmountOfJurorsForDispute(disputeId);

            case 4:
              numberOfJurors = _context23.sent;
              draws = [];
              draw = 1;

            case 7:
              if (!(draw <= numberOfJurors)) {
                _context23.next = 15;
                break;
              }

              _context23.next = 10;
              return _this2.isJurorDrawnForDispute(disputeId, draw, account);

            case 10:
              isJuror = _context23.sent;

              if (isJuror) {
                draws.push(draw);
              }

            case 12:
              draw++;
              _context23.next = 7;
              break;

            case 15:
              return _context23.abrupt('return', draws);

            case 16:
            case 'end':
              return _context23.stop();
          }
        }
      }, _callee23, _this2);
    }));

    return function (_x41, _x42) {
      return _ref25.apply(this, arguments);
    };
  }();

  this.getOpenDisputesForSession = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee24() {
    var currentSession, openDisputes, disputeId, dispute;
    return _regenerator2.default.wrap(function _callee24$(_context24) {
      while (1) {
        switch (_context24.prev = _context24.next) {
          case 0:
            _context24.next = 2;
            return _this2.loadContract();

          case 2:
            _context24.next = 4;
            return _this2.getSession();

          case 4:
            currentSession = _context24.sent;
            openDisputes = [];
            disputeId = 0;
            dispute = void 0;

          case 8:
            if (!1) {
              _context24.next = 27;
              break;
            }

            _context24.prev = 9;
            _context24.next = 12;
            return _this2.getDispute(disputeId);

          case 12:
            dispute = _context24.sent;
            _context24.next = 21;
            break;

          case 15:
            _context24.prev = 15;
            _context24.t0 = _context24['catch'](9);

            if (!(_context24.t0.message === errorConstants.UNABLE_TO_FETCH_DISPUTE)) {
              _context24.next = 19;
              break;
            }

            return _context24.abrupt('break', 27);

          case 19:
            console.error(_context24.t0);
            throw _context24.t0;

          case 21:
            if (!(dispute.arbitrableContractAddress === ethConstants.NULL_ADDRESS)) {
              _context24.next = 23;
              break;
            }

            return _context24.abrupt('break', 27);

          case 23:

            // If dispute is in the current session, add it to the result array
            if (dispute.firstSession + dispute.numberOfAppeals === currentSession) openDisputes.push(dispute);

            // Advance to the next dispute
            disputeId++;
            _context24.next = 8;
            break;

          case 27:
            return _context24.abrupt('return', openDisputes);

          case 28:
          case 'end':
            return _context24.stop();
        }
      }
    }, _callee24, _this2, [[9, 15]]);
  }));

  this.getAppealRuledAtTimestamp = function () {
    var _ref27 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee25(session) {
      var eventLog, ruledAtTimestamp;
      return _regenerator2.default.wrap(function _callee25$(_context25) {
        while (1) {
          switch (_context25.prev = _context25.next) {
            case 0:
              _context25.next = 2;
              return _this2._getNewPeriodEventLogForSession(session, arbitratorConstants.PERIOD.APPEAL);

            case 2:
              eventLog = _context25.sent;

              if (eventLog) {
                _context25.next = 5;
                break;
              }

              return _context25.abrupt('return', null);

            case 5:
              _context25.next = 7;
              return _this2._getTimestampForBlock(eventLog.blockNumber);

            case 7:
              ruledAtTimestamp = _context25.sent;
              return _context25.abrupt('return', ruledAtTimestamp * 1000);

            case 9:
            case 'end':
              return _context25.stop();
          }
        }
      }, _callee25, _this2);
    }));

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

  this.getDisputeDeadlineTimestamp = function () {
    var _ref28 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee26(session) {
      var eventLog, periodLength, periodStartTimestamp;
      return _regenerator2.default.wrap(function _callee26$(_context26) {
        while (1) {
          switch (_context26.prev = _context26.next) {
            case 0:
              _context26.next = 2;
              return _this2._getNewPeriodEventLogForSession(session, arbitratorConstants.PERIOD.VOTE);

            case 2:
              eventLog = _context26.sent;

              if (eventLog) {
                _context26.next = 5;
                break;
              }

              return _context26.abrupt('return', null);

            case 5:
              _context26.next = 7;
              return _this2.getTimeForPeriod(arbitratorConstants.PERIOD.VOTE);

            case 7:
              periodLength = _context26.sent;
              _context26.next = 10;
              return _this2._getTimestampForBlock(eventLog.blockNumber);

            case 10:
              periodStartTimestamp = _context26.sent;
              return _context26.abrupt('return', (periodLength + periodStartTimestamp) * 1000);

            case 12:
            case 'end':
              return _context26.stop();
          }
        }
      }, _callee26, _this2);
    }));

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

  this.getAppealCreationTimestamp = function () {
    var _ref29 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee27(session) {
      var eventLog, createdAtTimestamp;
      return _regenerator2.default.wrap(function _callee27$(_context27) {
        while (1) {
          switch (_context27.prev = _context27.next) {
            case 0:
              _context27.next = 2;
              return _this2._getNewPeriodEventLogForSession(session, arbitratorConstants.PERIOD.EXECUTE);

            case 2:
              eventLog = _context27.sent;

              if (eventLog) {
                _context27.next = 5;
                break;
              }

              return _context27.abrupt('return', null);

            case 5:
              _context27.next = 7;
              return _this2._getTimestampForBlock(eventLog.blockNumber);

            case 7:
              createdAtTimestamp = _context27.sent;
              return _context27.abrupt('return', createdAtTimestamp * 1000);

            case 9:
            case 'end':
              return _context27.stop();
          }
        }
      }, _callee27, _this2);
    }));

    return function (_x45) {
      return _ref29.apply(this, arguments);
    };
  }();

  this.getDisputeCreationEvent = function () {
    var _ref30 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee28(disputeId) {
      var eventLogs, i, log;
      return _regenerator2.default.wrap(function _callee28$(_context28) {
        while (1) {
          switch (_context28.prev = _context28.next) {
            case 0:
              _context28.next = 2;
              return _EventListener2.default.getEventLogs(_this2, 'DisputeCreation', 0, 'latest', { _disputeID: disputeId });

            case 2:
              eventLogs = _context28.sent;
              i = 0;

            case 4:
              if (!(i < eventLogs.length)) {
                _context28.next = 11;
                break;
              }

              log = eventLogs[i];

              if (!(log.args._disputeID.toNumber() === disputeId)) {
                _context28.next = 8;
                break;
              }

              return _context28.abrupt('return', log);

            case 8:
              i++;
              _context28.next = 4;
              break;

            case 11:
              return _context28.abrupt('return', null);

            case 12:
            case 'end':
              return _context28.stop();
          }
        }
      }, _callee28, _this2);
    }));

    return function (_x46) {
      return _ref30.apply(this, arguments);
    };
  }();

  this.getNetTokensForDispute = function () {
    var _ref31 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee29(disputeId, account) {
      var eventLogs, netPNK, i, event;
      return _regenerator2.default.wrap(function _callee29$(_context29) {
        while (1) {
          switch (_context29.prev = _context29.next) {
            case 0:
              _context29.next = 2;
              return _EventListener2.default.getEventLogs(_this2, 'TokenShift', 0, 'latest', { _account: account });

            case 2:
              eventLogs = _context29.sent;
              netPNK = 0;

              for (i = 0; i < eventLogs.length; i++) {
                event = eventLogs[i];

                if (event.args._disputeID.toNumber() === disputeId) netPNK += event.args._amount.toNumber();
              }

              return _context29.abrupt('return', _this2._Web3Wrapper.fromWei(netPNK, 'ether'));

            case 6:
            case 'end':
              return _context29.stop();
          }
        }
      }, _callee29, _this2);
    }));

    return function (_x47, _x48) {
      return _ref31.apply(this, arguments);
    };
  }();

  this._getTimestampForBlock = function () {
    var _ref32 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee30(blockNumber) {
      return _regenerator2.default.wrap(function _callee30$(_context30) {
        while (1) {
          switch (_context30.prev = _context30.next) {
            case 0:
              _context30.next = 2;
              return _this2._Web3Wrapper.getBlock(blockNumber);

            case 2:
              return _context30.abrupt('return', _context30.sent.timestamp);

            case 3:
            case 'end':
              return _context30.stop();
          }
        }
      }, _callee30, _this2);
    }));

    return function (_x49) {
      return _ref32.apply(this, arguments);
    };
  }();

  this._getNewPeriodEventLogForSession = function () {
    var _ref33 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee31(session, periodNumber) {
      var logs, i, eventLog;
      return _regenerator2.default.wrap(function _callee31$(_context31) {
        while (1) {
          switch (_context31.prev = _context31.next) {
            case 0:
              _context31.next = 2;
              return _EventListener2.default.getEventLogs(_this2, 'NewPeriod', 0, 'latest', { _session: [session] });

            case 2:
              logs = _context31.sent;
              i = 0;

            case 4:
              if (!(i < logs.length)) {
                _context31.next = 11;
                break;
              }

              eventLog = logs[i];

              if (!(eventLog.args._period.toNumber() === periodNumber)) {
                _context31.next = 8;
                break;
              }

              return _context31.abrupt('return', eventLog);

            case 8:
              i++;
              _context31.next = 4;
              break;

            case 11:
              return _context31.abrupt('return', null);

            case 12:
            case 'end':
              return _context31.stop();
          }
        }
      }, _callee31, _this2);
    }));

    return function (_x50, _x51) {
      return _ref33.apply(this, arguments);
    };
  }();

  this.getData = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee32() {
    var _ref35, _ref36, pinakionContractAddress, rngContractAddress, period, session, lastPeriodChange;

    return _regenerator2.default.wrap(function _callee32$(_context32) {
      while (1) {
        switch (_context32.prev = _context32.next) {
          case 0:
            _context32.next = 2;
            return _this2.loadContract();

          case 2:
            _context32.next = 4;
            return _promise2.default.all([_this2.contractInstance.pinakion(), _this2.contractInstance.rng(), _this2.contractInstance.period(), _this2.contractInstance.session(), _this2.contractInstance.lastPeriodChange()]);

          case 4:
            _ref35 = _context32.sent;
            _ref36 = (0, _slicedToArray3.default)(_ref35, 5);
            pinakionContractAddress = _ref36[0];
            rngContractAddress = _ref36[1];
            period = _ref36[2];
            session = _ref36[3];
            lastPeriodChange = _ref36[4];
            return _context32.abrupt('return', {
              pinakionContractAddress: pinakionContractAddress,
              rngContractAddress: rngContractAddress,
              period: period.toNumber(),
              session: session.toNumber(),
              lastPeriodChange: lastPeriodChange.toNumber()
            });

          case 12:
          case 'end':
            return _context32.stop();
        }
      }
    }, _callee32, _this2);
  }));
};

exports.default = Kleros;
//# sourceMappingURL=Kleros.js.map