'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 _abi = require('./abi');var abis = _interopRequireWildcard(_abi);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 _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}

var REGISTRY_V1_HASHES = [
'0x34f7c51bbb1b1902fbdabfdf04811100f5c9f998f26dd535d2f6f977492c748e', // ropsten
'0x64c3ee34851517a9faecd995c102b339f03e564ad6772dc43a26f993238b20ec' // homestead
];var

Registry = function () {


  function Registry(api) {_classCallCheck(this, Registry);this._registryContract = null;
    this._api = api;

    this._contracts = {};
    this._pendingContracts = {};

    this._instance = null;
    this._fetching = false;
    this._queue = [];

    this.getInstance();
  }_createClass(Registry, [{ key: 'getInstance', value: function getInstance()

    {var _this = this;
      if (this._instance) {
        return Promise.resolve(this._instance);
      }

      if (this._fetching) {
        return new Promise(function (resolve) {
          _this._queue.push({ resolve: resolve });
        });
      }

      this._fetching = true;

      return this.fetchContract().
      then(function (contract) {
        _this._fetching = false;
        _this._instance = contract.instance;

        _this._queue.forEach(function (queued) {
          queued.resolve(_this._instance);
        });

        _this._queue = [];

        return _this._instance;
      });
    } }, { key: 'getContract', value: function getContract(

    _name) {var _this2 = this;
      var name = _name.toLowerCase();

      if (this._contracts[name]) {
        return Promise.resolve(this._contracts[name]);
      }

      if (this._pendingContracts[name]) {
        return this._pendingContracts[name];
      }

      var promise = this.
      lookupAddress(name).
      then(function (address) {
        _this2._contracts[name] = _this2._api.newContract(abis[name], address);
        delete _this2._pendingContracts[name];
        return _this2._contracts[name];
      });

      this._pendingContracts[name] = promise;

      return promise;
    } }, { key: 'getContractInstance', value: function getContractInstance(

    _name) {
      return this.
      getContract(_name).
      then(function (contract) {return contract.instance;});
    } }, { key: 'fetchContract', value: function fetchContract()

    {var _this3 = this;
      if (this._registryContract) {
        return Promise.resolve(this._registryContract);
      }

      return this._api.parity.
      registryAddress().
      then(function (address) {return Promise.all([address, _this3._api.eth.getCode(address)]);}).
      then(function (_ref) {var _ref2 = _slicedToArray(_ref, 2),address = _ref2[0],code = _ref2[1];
        var codeHash = _this3._api.util.sha3(code);
        var version = REGISTRY_V1_HASHES.includes(codeHash) ?
        1 :
        2;
        var abi = version === 1 ?
        abis.registry :
        abis.registry2;
        var contract = _this3._api.newContract(abi, address);

        // Add support for previous `set` and `get` methods
        if (!contract.instance.get && contract.instance.getData) {
          contract.instance.get = contract.instance.getData;
        }

        if (contract.instance.get && !contract.instance.getData) {
          contract.instance.getData = contract.instance.get;
        }

        if (!contract.instance.set && contract.instance.setData) {
          contract.instance.set = contract.instance.setData;
        }

        if (contract.instance.set && !contract.instance.setData) {
          contract.instance.setData = contract.instance.set;
        }

        console.log('registry at ' + address + ', code ' + codeHash + ', version ' + version);
        _this3._registryContract = contract;
        return _this3._registryContract;
      });
    } }, { key: '_createGetParams', value: function _createGetParams(

    _name, key) {
      var name = _name.toLowerCase();
      var sha3 = this._api.util.sha3.text(name);

      return [sha3, key];
    } }, { key: 'lookupAddress', value: function lookupAddress(

    name) {var _this4 = this;
      return this.
      getInstance().
      then(function (instance) {
        return instance.getAddress.call({}, _this4._createGetParams(name, 'A'));
      }).
      then(function (address) {
        console.log('[lookupAddress]', name + ': ' + address);
        return address;
      });
    } }, { key: 'lookupMeta', value: function lookupMeta(

    name, key) {var _this5 = this;
      return this.
      getInstance().
      then(function (instance) {
        return instance.get.call({}, _this5._createGetParams(name, key));
      });
    } }]);return Registry;}();exports.default = Registry;