(function() {
  var Consumer, Disposable, Provider, ServiceHub;

  Disposable = require('event-kit').Disposable;

  Consumer = require('./consumer');

  Provider = require('./provider');

  module.exports = ServiceHub = (function() {
    function ServiceHub() {
      this.consumers = [];
      this.providers = [];
    }

    ServiceHub.prototype.provide = function(keyPath, version, service) {
      var consumer, provider, servicesByVersion, _i, _len, _ref;
      if (service != null) {
        servicesByVersion = {};
        servicesByVersion[version] = service;
      } else {
        servicesByVersion = version;
      }
      provider = new Provider(keyPath, servicesByVersion);
      this.providers.push(provider);
      _ref = this.consumers;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        consumer = _ref[_i];
        if (!consumer.isDestroyed) {
          provider.provide(consumer);
        }
      }
      return new Disposable((function(_this) {
        return function() {
          var index;
          provider.destroy();
          index = _this.providers.indexOf(provider);
          return _this.providers.splice(index, 1);
        };
      })(this));
    };

    ServiceHub.prototype.consume = function(keyPath, versionRange, callback) {
      var consumer, provider, _i, _len, _ref;
      consumer = new Consumer(keyPath, versionRange, callback);
      this.consumers.push(consumer);
      _ref = this.providers;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        provider = _ref[_i];
        provider.provide(consumer);
      }
      return new Disposable((function(_this) {
        return function() {
          var index;
          index = _this.consumers.indexOf(consumer);
          if (index >= 0) {
            return _this.consumers.splice(index, 1);
          }
        };
      })(this));
    };

    ServiceHub.prototype.clear = function() {
      var provider, _i, _len, _ref;
      _ref = this.providers;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        provider = _ref[_i];
        provider.destroy();
      }
      this.providers = [];
      return this.consumers = [];
    };

    return ServiceHub;

  })();

}).call(this);
