'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 _ArbitrableTransaction = require('kleros-interaction/build/contracts/ArbitrableTransaction');

var _ArbitrableTransaction2 = _interopRequireDefault(_ArbitrableTransaction);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

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

var ethConstants = _interopRequireWildcard(_eth);

var _contract = require('../../../constants/contract');

var contractConstants = _interopRequireWildcard(_contract);

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

var errorConstants = _interopRequireWildcard(_error);

var _Arbitrable2 = require('./Arbitrable');

var _Arbitrable3 = _interopRequireDefault(_Arbitrable2);

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

var _deployContractAsync2 = _interopRequireDefault(_deployContractAsync);

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 an Arbitrable Transaction contract deployed on the blockchain.
 */
var ArbitrableTransaction = function (_Arbitrable) {
  (0, _inherits3.default)(ArbitrableTransaction, _Arbitrable);

  /**
   * Constructor ArbitrableTransaction.
   * @param {object} web3Provider instance
   * @param {string} contractAddress of the contract
   */
  function ArbitrableTransaction(web3Provider, contractAddress) {
    (0, _classCallCheck3.default)(this, ArbitrableTransaction);

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

    _initialiseProps.call(_this);

    return _this;
  }

  /**
   * Deploy ArbitrableTransaction.
   * @param {object} account Ethereum account (default account[0])
   * @param {number} value funds to be placed in contract
   * @param {string} hashContract Keccak hash of the plain English contract. (default null hashed)
   * @param {string} arbitratorAddress The address of the arbitrator contract
   * @param {number} timeout Time after which a party automatically loose a dispute. (default 3600)
   * @param {string} partyB The recipient of the transaction. (default account[1])
   * @param {bytes} arbitratorExtraData Extra data for the arbitrator. (default empty string)
   * @param {object} web3Provider web3 provider object
   * @returns {object} truffle-contract Object | err The deployed contract or an error
   */


  /**
   * Pay the party B. To be called when the good is delivered or the service rendered.
   * @param {string} account - Ethereum account (default account[0]).
   * @param {string} contractAddress - The address of the arbitrator contract.
   * @returns {object} - The result transaction object.
   */


  /**
   * Pay the arbitration fee to raise a dispute. To be called by the party A.
   * @param {string} account - Ethereum account (default account[0]).
   * @param {number} arbitrationCost - Amount to pay the arbitrator. (default 0.15 ether).
   * @returns {object} - The result transaction object.
   */


  /**
   * Pay the arbitration fee to raise a dispute. To be called by the party B.
   * @param {string} account Ethereum account (default account[1]).
   * @param {number} arbitrationCost Amount to pay the arbitrator. (default 10000 wei).
   * @returns {object} - The result transaction object.
   */


  /**
   * Submit evidence.
   * @param {string} account ETH address of user.
   * @param {string} name name of evidence.
   * @param {string} description description of evidence.
   * @param {string} url A link to an evidence using its URI.
   * @returns {string} txHash Hash transaction.
   */


  /**
   * Call by partyA if partyB is timeout
   * @param {string} account ETH address of user
   * @returns {object} The result transaction object.
   */


  /**
   * Call by partyB if partyA is timeout.
   * @param {string} account - ETH address of user.
   * @param {string} contractAddress - ETH address of contract.
   * @returns {object} The result transaction object.
   */


  /**
   * Appeal an appealable ruling.
   * @param {string} account Ethereum account (default account[0]).
   * @param {bytes} extraData for the arbitrator appeal procedure.
   * @param {number} appealCost Amount to pay the arbitrator. (default 0.35 ether).
   * @returns {object} - The result transaction object.
   */


  /**
   * Data of the contract
   * @returns {object} Object Data of the contract.
   */


  return ArbitrableTransaction;
}(_Arbitrable3.default);

ArbitrableTransaction.deploy = function () {
  var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(account) {
    var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ethConstants.TRANSACTION.VALUE;
    var arbitratorAddress = arguments[2];
    var timeout = arguments[3];
    var partyB = arguments[4];
    var arbitratorExtraData = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : '';
    var metaEvidenceUri = arguments[6];
    var web3Provider = arguments[7];
    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, _ArbitrableTransaction2.default, web3Provider, arbitratorAddress, timeout, partyB, arbitratorExtraData, metaEvidenceUri);

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

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

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

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

  this.pay = function () {
    var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      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.prev = 2;
              return _context2.abrupt('return', _this2.contractInstance.pay({
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: 0
              }));

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

              console.error(_context2.t0);
              throw new Error(errorConstants.UNABLE_TO_PAY_SELLER);

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

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

  this.payArbitrationFeeByPartyA = function () {
    var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      var arbitrationCost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;
      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.prev = 2;
              return _context3.abrupt('return', _this2.contractInstance.payArbitrationFeeByPartyA({
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: _this2._Web3Wrapper.toWei(arbitrationCost, 'ether')
              }));

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

              console.error(_context3.t0);
              throw new Error(errorConstants.UNABLE_TO_PAY_ARBITRATION_FEE);

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

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

  this.payArbitrationFeeByPartyB = 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(1);
      var arbitrationCost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;
      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.prev = 2;
              return _context4.abrupt('return', _this2.contractInstance.payArbitrationFeeByPartyB({
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: _this2._Web3Wrapper.toWei(arbitrationCost, 'ether')
              }));

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

              console.error(_context4.t0);
              throw new Error(errorConstants.UNABLE_TO_PAY_ARBITRATION_FEE);

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

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

  this.submitEvidence = function () {
    var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      var url = arguments[1];
      var txHashObj;
      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.next = 4;
              return _this2.contractInstance.submitEvidence(url, {
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: 0
              });

            case 4:
              txHashObj = _context5.sent;
              return _context5.abrupt('return', txHashObj.tx);

            case 6:
            case 'end':
              return _context5.stop();
          }
        }
      }, _callee5, _this2);
    }));

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

  this.callTimeOutPartyA = function () {
    var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(0);
      var status, timeout, lastInteraction;
      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.next = 4;
              return _this2.contractInstance.status();

            case 4:
              status = _context6.sent.toNumber();
              _context6.next = 7;
              return _this2.contractInstance.timeout();

            case 7:
              timeout = _context6.sent.toNumber();
              _context6.next = 10;
              return _this2.contractInstance.lastInteraction();

            case 10:
              lastInteraction = _context6.sent.toNumber();

              if (!(status !== contractConstants.STATUS.WAITING_PARTY_B)) {
                _context6.next = 15;
                break;
              }

              throw new Error(errorConstants.CONTRACT_IS_NOT_WAITING_ON_OTHER_PARTY);

            case 15:
              if (!(Date.now() >= lastInteraction + timeout)) {
                _context6.next = 17;
                break;
              }

              throw new Error(errorConstants.TIMEOUT_NOT_REACHED);

            case 17:
              _context6.prev = 17;
              return _context6.abrupt('return', _this2.contractInstance.timeOutByPartyA({
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: 0
              }));

            case 21:
              _context6.prev = 21;
              _context6.t0 = _context6['catch'](17);

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

            case 25:
            case 'end':
              return _context6.stop();
          }
        }
      }, _callee6, _this2, [[17, 21]]);
    }));

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

  this.callTimeOutPartyB = function () {
    var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7() {
      var account = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2._Web3Wrapper.getAccount(1);
      var status, timeout, lastInteraction;
      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.next = 4;
              return _this2.contractInstance.status();

            case 4:
              status = _context7.sent;
              _context7.next = 7;
              return _this2.contractInstance.timeout();

            case 7:
              timeout = _context7.sent;
              _context7.next = 10;
              return _this2.contractInstance.lastInteraction();

            case 10:
              lastInteraction = _context7.sent;

              if (!(status !== contractConstants.STATUS.WAITING_PARTY_A)) {
                _context7.next = 15;
                break;
              }

              throw new Error(errorConstants.CONTRACT_IS_NOT_WAITING_ON_OTHER_PARTY);

            case 15:
              if (!(Date.now() >= lastInteraction + timeout)) {
                _context7.next = 17;
                break;
              }

              throw new Error(errorConstants.TIMEOUT_NOT_REACHED);

            case 17:
              _context7.prev = 17;
              return _context7.abrupt('return', _this2.contractInstance.timeOutByPartyB({
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: 0
              }));

            case 21:
              _context7.prev = 21;
              _context7.t0 = _context7['catch'](17);

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

            case 25:
            case 'end':
              return _context7.stop();
          }
        }
      }, _callee7, _this2, [[17, 21]]);
    }));

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

  this.appeal = 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);
      var extraData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x0;
      var appealCost = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.3;
      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;
              return _context8.abrupt('return', _this2.contractInstance.appeal(extraData, {
                from: account,
                gas: ethConstants.TRANSACTION.GAS,
                value: _this2._Web3Wrapper.toWei(appealCost, 'ether')
              }));

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

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

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

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

  this.getData = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9() {
    var _ref10, _ref11, arbitrator, extraData, timeout, partyA, partyB, status, arbitratorExtraData, disputeId, partyAFee, partyBFee, lastInteraction, amount, evidence, metaEvidence;

    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.next = 4;
            return _promise2.default.all([_this2.contractInstance.arbitrator(), _this2.contractInstance.arbitratorExtraData(),
            //  this.contractInstance.hashContract(),
            _this2.contractInstance.timeout(), _this2.contractInstance.partyA(), _this2.contractInstance.partyB(), _this2.contractInstance.status(), _this2.contractInstance.arbitratorExtraData(), _this2.contractInstance.disputeID(), _this2.contractInstance.partyAFee(), _this2.contractInstance.partyBFee(), _this2.contractInstance.lastInteraction(), _this2.contractInstance.amount(), _this2.getEvidence(), _this2.getMetaEvidence()]);

          case 4:
            _ref10 = _context9.sent;
            _ref11 = (0, _slicedToArray3.default)(_ref10, 14);
            arbitrator = _ref11[0];
            extraData = _ref11[1];
            timeout = _ref11[2];
            partyA = _ref11[3];
            partyB = _ref11[4];
            status = _ref11[5];
            arbitratorExtraData = _ref11[6];
            disputeId = _ref11[7];
            partyAFee = _ref11[8];
            partyBFee = _ref11[9];
            lastInteraction = _ref11[10];
            amount = _ref11[11];
            evidence = _ref11[12];
            metaEvidence = _ref11[13];
            return _context9.abrupt('return', {
              address: _this2.getContractAddress(),
              arbitrator: arbitrator,
              extraData: extraData,
              timeout: timeout.toNumber(),
              partyA: partyA,
              partyB: partyB,
              status: status.toNumber(),
              arbitratorExtraData: arbitratorExtraData,
              disputeId: disputeId.toNumber(),
              partyAFee: _this2._Web3Wrapper.fromWei(partyAFee, 'ether'),
              partyBFee: _this2._Web3Wrapper.fromWei(partyBFee, 'ether'),
              lastInteraction: lastInteraction.toNumber(),
              amount: amount.toNumber(),
              evidence: evidence,
              metaEvidence: metaEvidence
            });

          case 21:
          case 'end':
            return _context9.stop();
        }
      }
    }, _callee9, _this2);
  }));
};

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