"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

var _bn = _interopRequireDefault(require("bn.js"));

var _rxjs = require("rxjs");

var _operators = require("rxjs/operators");

var _types = require("@polkadot/types");

var _util = require("@polkadot/util");

var _idAndIndex = require("../accounts/idAndIndex");

var _bestNumber = require("../chain/bestNumber");

var _drr = require("../util/drr");

// Copyright 2017-2019 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
function calcBalances(_ref) {
  let [accountId, bestNumber, [freeBalance, reservedBalance, locks, vesting], accountNonce] = _ref;
  let lockedBalance = (0, _types.createType)('Balance');

  if (Array.isArray(locks)) {
    // only get the locks that are valid until passed the current block
    const totals = locks.filter(value => bestNumber && value.until.gt(bestNumber)); // get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699

    lockedBalance = totals[0] ? (0, _types.createType)('Balance', (0, _util.bnMax)(...totals.map((_ref2) => {
      let {
        amount
      } = _ref2;
      return amount;
    }))) : (0, _types.createType)('Balance');
  } // offset = balance locked at genesis, perBlock is the unlock amount


  const {
    offset,
    perBlock
  } = vesting.unwrapOr((0, _types.createType)('VestingSchedule'));
  const vestedNow = (0, _types.createType)('Balance', perBlock.mul(bestNumber));
  const vestedBalance = vestedNow.gt(offset) ? freeBalance : (0, _types.createType)('Balance', freeBalance.sub(offset).add(vestedNow)); // NOTE Workaround for this account on Alex (one of a couple reported) -
  //   5F7BJL6Z4m8RLtK7nXEqqpEqhBbd535Z3CZeYF6ccvaQAY6N
  // The locked is > the vested and ended up with the locked > free,
  // i.e. related to https://github.com/paritytech/polkadot/issues/225
  // (most probably due to movements from stash -> controller -> free)

  const availableBalance = (0, _types.createType)('Balance', (0, _util.bnMax)(new _bn.default(0), vestedBalance.sub(lockedBalance)));
  return {
    accountId,
    accountNonce,
    availableBalance,
    freeBalance,
    lockedBalance,
    reservedBalance,
    vestedBalance,
    votingBalance: (0, _types.createType)('Balance', freeBalance.add(reservedBalance))
  };
}

function queryBalances(api, accountId) {
  return api.queryMulti([[api.query.balances.freeBalance, accountId], [api.query.balances.reservedBalance, accountId], [api.query.balances.locks, accountId], [api.query.balances.vesting, accountId]]);
}
/**
 * @name all
 * @param {( AccountIndex | AccountId | Address | string )} address - An accounts Id in different formats.
 * @returns An object containing the results of various balance queries
 * @example
 * <BR>
 *
 * ```javascript
 * const ALICE = 'F7Hs';
 *
 * api.derive.balances.all(ALICE, ({ accountId, lockedBalance }) => {
 *   console.log(`The account ${accountId} has a locked balance ${lockedBalance} units.`);
 * });
 * ```
 */


function all(api) {
  return address => {
    return (0, _idAndIndex.idAndIndex)(api)(address).pipe((0, _operators.switchMap)((_ref3) => {
      let [accountId] = _ref3;
      return accountId ? (0, _rxjs.combineLatest)([(0, _rxjs.of)(accountId), (0, _bestNumber.bestNumber)(api)(), queryBalances(api, accountId), // FIXME This is having issues with Kusama, only use accountNonce atm
      // api.rpc.account && api.rpc.account.nextIndex
      //   ? api.rpc.account.nextIndex(accountId)
      //   // otherwise we end up with this: type 'Codec | Index' is not assignable to type 'Index'.
      //   : api.query.system.accountNonce<Index>(accountId)
      api.query.system.accountNonce(accountId)]) : (0, _rxjs.of)([(0, _types.createType)('AccountId'), (0, _types.createType)('BlockNumber'), [(0, _types.createType)('Balance'), (0, _types.createType)('Balance'), (0, _types.createType)('Vec<BalanceLock>'), (0, _types.createType)('Option<VestingSchedule>', null)], (0, _types.createType)('Index')]);
    }), (0, _operators.map)(calcBalances), (0, _drr.drr)());
  };
}