'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.default = undefined;var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}(); // Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.

var _lodash = require('lodash');

var _config = require('../../config');
var _upgradeParity = require('../../mobx/upgradeParity');var _upgradeParity2 = _interopRequireDefault(_upgradeParity);
var _testnet = require('../../util/testnet');

var _statusActions = require('./statusActions');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}

var log = (0, _config.getLogger)(_config.LOG_KEYS.Signer);
var instance = null;var

Status = function () {







  function Status(store, api) {var _this = this;_classCallCheck(this, Status);this._apiStatus = {};this._longStatus = {};this._minerSettings = {};this._timeoutIds = {};this._blockNumberSubscriptionId = null;this._timestamp = Date.now();this.






























































    getApiStatus = function () {var _api =
      _this._api,isConnected = _api.isConnected,isConnecting = _api.isConnecting,needsToken = _api.needsToken,secureToken = _api.secureToken;

      return {
        isConnected: isConnected,
        isConnecting: isConnecting,
        needsToken: needsToken,
        secureToken: secureToken };

    };this.


















    _subscribeBlockNumber = function () {
      return _this._api.
      subscribe('eth_blockNumber', function (error, blockNumber) {
        if (error || !blockNumber) {
          return;
        }

        _this._store.dispatch((0, _statusActions.statusBlockNumber)(blockNumber));

        _this._api.parity.
        getBlockHeaderByNumber(blockNumber).
        then(function (block) {
          if (!block) {
            return;
          }

          _this._store.dispatch((0, _statusActions.statusCollection)({
            blockTimestamp: block.timestamp,
            gasLimit: block.gasLimit }));

        }).
        catch(function (error) {
          console.warn('status._subscribeBlockNumber', 'getBlockHeaderByNumber', error);
        });
      }).
      then(function (blockNumberSubscriptionId) {
        _this._blockNumberSubscriptionId = blockNumberSubscriptionId;
      });
    };this.

    _updateStatus = (0, _lodash.debounce)(function (status) {
      _this._store.dispatch((0, _statusActions.statusCollection)(status));
    }, 2500, {
      maxWait: 5000 });this.


    _subscribeEthSyncing = function () {
      return _this._api.pubsub.
      eth.
      syncing(function (error, syncing) {
        if (error) {
          return;
        }

        _this._updateStatus({ syncing: syncing });
      });
    };this.

    _subscribeNetPeers = function () {
      return _this._api.pubsub.
      parity.
      netPeers(function (error, netPeers) {
        if (error || !netPeers) {
          return;
        }

        _this._store.dispatch((0, _statusActions.statusCollection)({ netPeers: netPeers }));
      });
    };this.













    _pollApiStatus = function () {
      var nextTimeout = function nextTimeout() {var timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
        if (_this._timeoutIds.status) {
          clearTimeout(_this._timeoutIds.status);
        }

        _this._timeoutIds.status = setTimeout(function () {return _this._pollApiStatus();}, timeout);
      };

      _this.updateApiStatus();

      if (!_this._api.isConnected) {
        nextTimeout(250);
      } else {
        nextTimeout();
      }
    };this.







    _pollLongStatus = function () {
      if (!_this._api.isConnected) {
        return Promise.resolve();
      }var

      nodeKindFull = _this._store.getState().nodeStatus.nodeKindFull;
      var defaultTimeout = (nodeKindFull === false ? 240 : 60) * 1000;

      var nextTimeout = function nextTimeout() {var timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultTimeout;
        if (_this._timeoutIds.longStatus) {
          clearTimeout(_this._timeoutIds.longStatus);
        }

        _this._timeoutIds.longStatus = setTimeout(function () {return _this._pollLongStatus();}, timeout);
      };

      var statusPromises = [
      _this._api.parity.nodeKind(),
      _this._api.web3.clientVersion(),
      _this._api.net.version(),
      _this._api.parity.netChain()];


      if (nodeKindFull) {
        statusPromises.push(_this._upgradeStore.checkUpgrade());
      }

      return Promise.
      all(statusPromises).
      then(function (_ref) {var _ref2 = _slicedToArray(_ref, 4),nodeKind = _ref2[0],clientVersion = _ref2[1],netVersion = _ref2[2],netChain = _ref2[3];
        var isTest = (0, _testnet.isTestnet)(netVersion);

        var nodeKindFull = nodeKind &&
        nodeKind.availability === 'personal' &&
        nodeKind.capability === 'full';

        var longStatus = {
          nodeKind: nodeKind,
          nodeKindFull: nodeKindFull,
          clientVersion: clientVersion,
          netChain: netChain,
          netVersion: netVersion,
          isTest: isTest };


        if (!(0, _lodash.isEqual)(longStatus, _this._longStatus)) {
          _this._store.dispatch((0, _statusActions.statusCollection)(longStatus));
          _this._longStatus = longStatus;
        }
      }).
      then(function () {
        nextTimeout();
      }).
      catch(function (error) {
        console.error('_pollLongStatus', error);
        nextTimeout(30000);
      });
    };this._api = api;this._store = store;this._upgradeStore = _upgradeParity2.default.get(api);this.updateApiStatus();}_createClass(Status, [{ key: 'updateApiStatus', value: function updateApiStatus() {var apiStatus = this.getApiStatus();log.debug('status::updateApiStatus', apiStatus);if (!(0, _lodash.isEqual)(apiStatus, this._apiStatus)) {this._store.dispatch((0, _statusActions.statusCollection)(apiStatus));this._apiStatus = apiStatus;}} }, { key: '_clearTimeouts', value: function _clearTimeouts() {Object.values(this._timeoutIds).forEach(function (timeoutId) {clearTimeout(timeoutId);});} }, { key: '_unsubscribeBlockNumber', value: function _unsubscribeBlockNumber() {var _this2 = this;if (this._blockNumberSubscriptionId) {return this._api.unsubscribe(this._blockNumberSubscriptionId).then(function () {_this2._blockNumberSubscriptionId = null;});}return Promise.resolve();} /**
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * The data fetched here should not change
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * unless Parity is restarted. They are thus
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * fetched every 30s just in case, and whenever
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * the client got reconnected.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */ }], [{ key: 'init', value: function init(store) {var _store$getState = store.getState(),api = _store$getState.api;if (!instance) {instance = new Status(store, api);}return instance;} }, { key: 'get', value: function get(store) {if (!instance && store) {return Status.init(store);} else if (!instance) {throw new Error('The Status Provider has not been initialized yet');}return instance;} }, { key: 'start', value: function start() {var self = instance;log.debug('status::start');var promises = [self._subscribeBlockNumber(), self._subscribeNetPeers(), self._subscribeEthSyncing(), self._pollLongStatus(), self._pollApiStatus()];return Status.stop().then(function () {return Promise.all(promises);});} }, { key: 'stop', value: function stop() {if (!instance) {return Promise.resolve();}var self = instance;log.debug('status::stop');self._clearTimeouts();return self._unsubscribeBlockNumber().catch(function (error) {console.error('status::stop', error);}).then(function () {return self.updateApiStatus();});} }]);return Status;}();exports.default = Status;