import * as tsplus_module_1 from "@tsplus/stdlib/collections/mutable/MutableHashMap/empty";
import * as tsplus_module_2 from "@effect/core/io/Metrics/MetricListener";
import * as tsplus_module_3 from "@effect/core/io/Metrics/MetricPair";
import * as tsplus_module_4 from "@tsplus/stdlib/collections/HashSet/from";
import * as tsplus_module_5 from "@tsplus/stdlib/data/Maybe/toUndefined";
import * as tsplus_module_6 from "@effect/core/io/Metrics/MetricHooks";
import * as tsplus_module_7 from "@effect/core/io/Metrics/MetricHook";
import * as tsplus_module_8 from "@tsplus/stdlib/collections/mutable/MutableHashMap/has";
import { CounterKey, FrequencyKey, GaugeKey, HistogramKey, SummaryKey } from "@effect/core/io/Metrics/MetricKeyType";
export class MetricRegistry {
  constructor() {
    this.map = tsplus_module_1.empty();
    this.listeners = new Set();
    this.listener = new tsplus_module_2.MetricListener(key => update => {
      for (const listener of this.listeners) {
        listener.unsafeUpdate(key)(update);
      }
    });
  }

  installListener(listener) {
    this.listeners.add(listener);
  }

  removeListener(listener) {
    this.listeners.delete(listener);
  }

  snapshot() {
    const result = [];

    for (const {
      tuple: [key, hook]
    } of this.map) {
      result.push(tsplus_module_3.unsafeMake(key, hook.get()));
    }

    return tsplus_module_4.from(result);
  }

  get(key) {
    const hook = tsplus_module_5.toUndefined(this.map.get(key));

    if (hook == null) {
      if (key.keyType instanceof CounterKey) {
        return this.getCounter(key);
      }

      if (key.keyType instanceof GaugeKey) {
        return this.getGauge(key);
      }

      if (key.keyType instanceof FrequencyKey) {
        return this.getFrequency(key);
      }

      if (key.keyType instanceof HistogramKey) {
        return this.getHistogram(key);
      }

      if (key.keyType instanceof SummaryKey) {
        return this.getSummary(key);
      }

      throw new Error("Bug, unknown MetricKeyType");
    } else {
      return hook;
    }
  }

  getCounter(key) {
    let value = tsplus_module_5.toUndefined(this.map.get(key));

    if (value == null) {
      const updater = this.listener.unsafeUpdate(key);
      const counter = tsplus_module_7.onUpdate(tsplus_module_6.counter(key), updater);

      if (!tsplus_module_8.has_(this.map, key)) {
        this.map.set(key, counter);
      }

      value = counter;
    }

    return value;
  }

  getGauge(key) {
    let value = tsplus_module_5.toUndefined(this.map.get(key));

    if (value == null) {
      const updater = this.listener.unsafeUpdate(key);
      const gauge = tsplus_module_7.onUpdate(tsplus_module_6.gauge(key, 0), updater);

      if (!tsplus_module_8.has_(this.map, key)) {
        this.map.set(key, gauge);
      }

      value = gauge;
    }

    return value;
  }

  getFrequency(key) {
    let value = tsplus_module_5.toUndefined(this.map.get(key));

    if (value == null) {
      const updater = this.listener.unsafeUpdate(key);
      const frequency = tsplus_module_7.onUpdate(tsplus_module_6.frequency(key), updater);

      if (!tsplus_module_8.has_(this.map, key)) {
        this.map.set(key, frequency);
      }

      value = frequency;
    }

    return value;
  }

  getHistogram(key) {
    let value = tsplus_module_5.toUndefined(this.map.get(key));

    if (value == null) {
      const updater = this.listener.unsafeUpdate(key);
      const histogram = tsplus_module_7.onUpdate(tsplus_module_6.histogram(key), updater);

      if (!tsplus_module_8.has_(this.map, key)) {
        this.map.set(key, histogram);
      }

      value = histogram;
    }

    return value;
  }

  getSummary(key) {
    let value = tsplus_module_5.toUndefined(this.map.get(key));

    if (value == null) {
      const updater = this.listener.unsafeUpdate(key);
      const summary = tsplus_module_7.onUpdate(tsplus_module_6.summary(key), updater);

      if (!tsplus_module_8.has_(this.map, key)) {
        this.map.set(key, summary);
      }

      value = summary;
    }

    return value;
  }

}
//# sourceMappingURL=MetricRegistry.mjs.map