module.exports = function targetEnvironments() {
  var _targets = Object.create(null);
  var _activeCount = 0;

  var checkAllowed = function(target) {
    if (!(target in _targets)) {
      throw new Error('Error accessing target "' + target + '". It is not in the list of allowed targets: ' + Object.keys(_targets));
    }
  };

  var updateActiveCount = function() {
    _activeCount = 0;
    for(target in _targets) {
      if (_targets[target]) _activeCount++;
    }
  };

  return {
    addAllowed: function(target, isActive) {
      _targets[target] = !!isActive;
      updateActiveCount();
    },
    removeAllowed: function(target) {
      delete _targets[target];
      updateActiveCount();
    },
    activate: function(target) {
      checkAllowed(target);
      _targets[target] = true;
      updateActiveCount();
    },
    deactivate: function(target) {
      checkAllowed(target);
      _targets[target] = false;
      updateActiveCount();
    },
    isActive: function(target) {
      checkAllowed(target);
      return _targets[target];
    },
    hasActive: function() {
      return _activeCount > 0;
    },
    someActive: function(targets) {
      for(var i=0,ii=targets.length; i<ii; i++) {
        if (this.isActive(targets[i])) return true;
      }
      return false;
    }
  };
};