'use strict';

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

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _getOwnPropertyNames = require('babel-runtime/core-js/object/get-own-property-names');

var _getOwnPropertyNames2 = _interopRequireDefault(_getOwnPropertyNames);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * delegate calls from a baseClass to a providerClass if the call does not exist in base class
 * @param {object} baseClass - The base object that has first priority to make calls
 * @param {object} providerClass - The class whose methods will be called by baseClass
 * @param {function} middlewareCall - <optional> Middleware function that can act as
 * intermediary between base and provider. Should take a two params which is the provider
 * classes method call and the params passed
 */
var delegateCalls = function delegateCalls(baseClass, providerClass, middlewareCall) {
  // we don't want to delegate any calls that are part of the base class
  var existingMethods = (0, _getOwnPropertyNames2.default)(baseClass).concat((0, _getPrototypeOf2.default)(baseClass));
  // methods of provider
  var providerMethods = (0, _getOwnPropertyNames2.default)(providerClass);
  // calls we will delegate
  var delegatableMethods = providerMethods.filter(function (method) {
    if (!providerClass.hasOwnProperty(method) || typeof providerClass[method] !== 'function') {
      return false;
    }

    return !_lodash2.default.includes(existingMethods, method);
  });

  // delegate calls in baseClass
  delegatableMethods.forEach(function (methodName) {
    var curriedCall = void 0;
    if (middlewareCall) curriedCall = function curriedCall() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      return middlewareCall.apply(undefined, [providerClass[methodName]].concat(args));
    };else curriedCall = function curriedCall() {
      return providerClass[methodName].apply(providerClass, arguments);
    };
    // set method in baseClass
    baseClass[methodName] = curriedCall;
  });
};

/**
{ constant: true,
  inputs: [],
  name: 'lastPeriodChange',
  outputs: [ [Object] ],
  payable: false,
  stateMutability: 'view',
  type: 'function' },
*/

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