import _defineProperty from "@babel/runtime/helpers/defineProperty";
function isUndefined(x) {
  return x === undefined;
}
export default class ProviderFactory {
  constructor() {
    _defineProperty(this, "providers", new Map());
    _defineProperty(this, "subscribers", new Map());
  }
  static create(providers) {
    const providerFactory = new ProviderFactory();
    const keys = Object.keys(providers);
    keys.forEach(name => {
      providerFactory.setProvider(name, providers[name]);
    });
    return providerFactory;
  }
  destroy() {
    this.providers.clear();
    this.subscribers.clear();
  }
  isEmpty() {
    return !this.providers.size && !this.subscribers.size;
  }
  setProvider(name, provider) {
    // Do not trigger notifyUpdate if provider is the same.
    if (this.providers.get(name) === provider) {
      return;
    }
    if (!isUndefined(provider)) {
      this.providers.set(name, provider);
    } else {
      this.providers.delete(name);
    }
    this.notifyUpdated(name, provider);
  }
  removeProvider(name) {
    this.providers.delete(name);
    this.notifyUpdated(name);
  }
  subscribe(name, handler) {
    const handlers = this.subscribers.get(name) || [];
    handlers.push(handler);
    this.subscribers.set(name, handlers);
    const provider = this.providers.get(name);
    if (provider) {
      handler(name, provider);
    }
  }
  unsubscribe(name, handler) {
    const handlers = this.subscribers.get(name);
    if (!handlers) {
      return;
    }
    const index = handlers.indexOf(handler);
    if (index !== -1) {
      handlers.splice(index, 1);
    }
    if (handlers.length === 0) {
      this.subscribers.delete(name);
    } else {
      this.subscribers.set(name, handlers);
    }
  }
  unsubscribeAll(name) {
    const handlers = this.subscribers.get(name);
    if (!handlers) {
      return;
    }
    this.subscribers.delete(name);
  }
  hasProvider(name) {
    return this.providers.has(name);
  }
  notifyUpdated(name, provider) {
    const handlers = this.subscribers.get(name);
    if (!handlers) {
      return;
    }
    handlers.forEach(handler => {
      handler(name, provider);
    });
  }
}