'use strict';

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

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

var _regenerator2 = _interopRequireDefault(_regenerator);

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

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

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

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _isRequired = require('./utils/isRequired');

var _isRequired2 = _interopRequireDefault(_isRequired);

var _Web3Wrapper = require('./utils/Web3Wrapper');

var _Web3Wrapper2 = _interopRequireDefault(_Web3Wrapper);

var _StoreProviderWrapper = require('./utils/StoreProviderWrapper');

var _StoreProviderWrapper2 = _interopRequireDefault(_StoreProviderWrapper);

var _contracts = require('./contracts');

var contracts = _interopRequireWildcard(_contracts);

var _resources = require('./resources');

var resources = _interopRequireWildcard(_resources);

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 }; }

/**
 * The Kleros Api provides access to the full suite of functionality. It will initialize
 * contract instances for you when possible and creates an object that you can use to
 * call all of the other api modules. If you are only going to be interacting with
 * specific apis, or you don't want certain functionality such as the off chain store,
 * you might find it easier to initialze a specific instance of the api you want.
 */
var Kleros =

/**
 * Instantiates a new Kelros instance that provides the public interface
 * to Kleros contracts and library. All params are required. To use an individual
 * portion of the API import a class and initialize it yourself.
 * @param {string} ethereumProvider - The Web3.js Provider instance you would like the
 *                 Kleros.js library to use for interacting with the
 *                 Ethereum network.
 * @param {string} storeUri - The storage provider uri used to
 *                      get metadata from the cloud for the UI. e.g. Kleros-Store,
 *                      IPFS, Swarm etc.
 * @param {string} arbitratorAddress - Address of the arbitrator contract we should
 *                 use when initializing KlerosPOC
 * @param {string} arbitrableContractAddress - Address of the arbitrator contract we should
 *                 use when initializing KlerosPOC
 * @param {string} authToken - Signed token cooresponding to the user profile address.
 */
function Kleros() {
  var ethereumProvider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : (0, _isRequired2.default)('ethereumProvider');
  var storeUri = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _isRequired2.default)('storeUri');
  var arbitratorAddress = arguments[2];
  var arbitrableContractAddress = arguments[3];
  var authToken = arguments[4];
  (0, _classCallCheck3.default)(this, Kleros);

  _initialiseProps.call(this);

  // NOTE we default to KlerosPOC and ArbitrableTransaction
  var _klerosPOC = new contracts.implementations.arbitrator.KlerosPOC(ethereumProvider, arbitratorAddress);
  var _arbitrableTransaction = new contracts.implementations.arbitrable.ArbitrableTransaction(ethereumProvider, arbitrableContractAddress);

  // **************************** //
  // *   INITIALIZED CLASSES    * //
  // **************************** //
  // KLEROS WRAPPERS
  this.web3Wrapper = new _Web3Wrapper2.default(ethereumProvider);
  this.storeWrapper = new _StoreProviderWrapper2.default(storeUri, authToken);
  // ARBITRATOR
  this.arbitrator = new contracts.abstractions.Arbitrator(_klerosPOC, this.storeWrapper);
  // ARBITRABLE CONTRACTS
  this.arbitrable = new contracts.abstractions.Arbitrable(_arbitrableTransaction, this.storeWrapper);
  // DISPUTES
  this.disputes = new resources.Disputes(this.arbitrator, this.arbitrable, this.storeWrapper);
  // NOTIFICATIONS
  this.notifications = new resources.Notifications(this.arbitrator, this.arbitrable, this.storeWrapper);
  // AUTH
  this.auth = new resources.Auth(this.web3Wrapper, this.storeWrapper);
}

/**
 * Set a new arbitrable contract for Kleros instance of arbitrableContracts
 * @param {string} contractAddress - Address of arbitrable contract
 */


/**
 * Bootstraps an EventListener and adds all Kleros handlers for event logs. Use
 * this if you want to watch the chain for notifications, or are using the off chain
 * store for metadata.
 * @param {string} account Address of the user
 * @param {function} callback The function to be called once a notification
 */


/**
 * Stop watching for events on the Arbitrator initialized in the Kleros Instance.
 */


/**
 * Sets the store provider uri for all higher level apis in the Kleros Instance.
 * @param {string} storeUri - The URI that the store provider will use
 */
;

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

  this.web3Wrapper = {};
  this.storeWrapper = {};
  this.eventListener = null;

  this.setArbitrableContractAddress = function (contractAddress) {
    _this.arbitrable.setContractInstance(contractAddress);
  };

  this.watchForEvents = function () {
    var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(account, callback // for notification callback
    ) {
      var fromBlock;
      return _regenerator2.default.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              // stop current event listeners
              if (_this.eventListener) {
                _this.eventListener.stopWatchingForEvents();
              }
              // reinitialize with current arbitrator contract instance
              _this.eventListener = new _EventListener2.default([_this.arbitrator]);
              // add handlers for notifications
              _this.notifications.registerArbitratorNotifications(account, _this.eventListener, callback);
              // add handlers for event driven store updates
              _this.disputes.registerStoreUpdateEventListeners(account, _this.eventListener);
              // fetch last block for user
              _context.next = 6;
              return _this.storeWrapper.getLastBlock(account);

            case 6:
              fromBlock = _context.sent;

              // start event listener
              _this.eventListener.watchForEvents(fromBlock);

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

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

  this.stopWatchingForEvents = function () {
    if (_this.eventListener) _this.eventListener.stopWatchingForEvents(_this.arbitrator);
  };

  this.setStoreProvider = function (storeUri) {
    _this.storeWrapper = new _StoreProviderWrapper2.default(storeUri);

    _this.disputes.setStoreProviderInstance(_this.storeWrapper);
    _this.arbitrable.setStoreProviderInstance(_this.storeWrapper);
    _this.arbitrator.setStoreProviderInstance(_this.storeWrapper);
    _this.notifications.setStoreProviderInstance(_this.storeWrapper);
    _this.auth.setStoreProviderInstance(_this.storeWrapper);
  };
};

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