package net.onrc.onos.core.metrics;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * This class acts a singleton to hold the Metrics registry for ONOS.
 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
 * string-based naming scheme: COMPONENT.FEATURE.NAME.
 * Example: "Topology.Counters.TopologyUpdates".
 * The COMPONENT and FEATURE names have to be registered in advance before
 * a metric can be created. Example:
 * <pre>
 *   <code>
 *     private static final OnosMetrics.MetricsComponent COMPONENT =
 *         OnosMetrics.registerComponent("Topology");
 *     private static final OnosMetrics.MetricsFeature FEATURE =
 *         COMPONENT.registerFeature("Counters");
 *     private final Counter counterTopologyUpdates =
 *         OnosMetrics.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
 *   </code>
 * </pre>
 * Gauges are slightly different because they are not created directly in
 * this class, but are allocated by the caller and passed in for registration:
 * <pre>
 *   <code>
 *     private final Gauge<Long> gauge =
 *         new {@literal Gauge<Long>}() {
 *             {@literal @}Override
 *             public Long getValue() {
 *                 return gaugeValue;
 *             }
 *         };
 *     OnosMetrics.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
 *   </code>
 * </pre>
 */
public final class OnosMetrics {

    /**
     * Hide constructor.  The only way to get the registry is through the
     * singleton getter.
     */
    private OnosMetrics() {}

    /**
     * Components that can hold Metrics.  This is used as the first part of
     * a Metric's name.
     */
    public interface MetricsComponent {
        /**
         * Fetches the name of the Component.
         *
         * @return name of the Component
         */
        public String getName();

        /**
         * Registers a Feature for this component.
         *
         * @param featureName name of the Feature to register
         * @return Feature object that can be used when creating Metrics
         */
        public MetricsFeature registerFeature(final String featureName);
    }

    /**
     * Features that can hold Metrics.  This is used as the second part of
     * a Metric's name.
     */
    public interface MetricsFeature {
        /**
         * Fetches the name of the Feature.
         *
         * @return name of the Feature
         */
        public String getName();
    }

    /**
     * Implementation of a class to represent the Component portion of a
     * Metric's name.
     */
    private static final class Component implements MetricsComponent {
        private final String name;

        /**
         * Constructs a component from a name.
         *
         * @param newName name of the component
         */
        private Component(final String newName) {
            name = newName;
        }

        @Override
        public String getName() {
            return name;
        }

        /**
         * Registry to hold the Features defined in this Component.
         */
        private ConcurrentMap<String, MetricsFeature> featuresRegistry =
                new ConcurrentHashMap<>();

        @Override
        public MetricsFeature registerFeature(final String featureName) {
            MetricsFeature feature = featuresRegistry.get(featureName);
            if (feature == null) {
                final MetricsFeature createdFeature = new Feature(featureName);
                feature = featuresRegistry.putIfAbsent(featureName, createdFeature);
                if (feature == null) {
                    feature = createdFeature;
                }
            }
            return feature;
        }
    }

    /**
     * Implementation of a class to represent the Feature portion of a Metric's
     * name.
     */
    private static final class Feature implements MetricsFeature {
        private final String name;

        /**
         * Constructs a Feature from a name.
         *
         * @param newName name of the Feature
         */
        private Feature(final String newName) {
            name = newName;
        }

        @Override
        public String getName() {
            return name;
        }
    }

    /**
     * Registry to hold the Components defined in the system.
     */
    private static ConcurrentMap<String, MetricsComponent> componentsRegistry =
            new ConcurrentHashMap<>();

    /**
     * Registers a component.
     *
     * @param name name of the Component to register
     * @return MetricsComponent object that can be used to create Metrics.
     */
    public static MetricsComponent registerComponent(final String name) {
        MetricsComponent component = componentsRegistry.get(name);
        if (component == null) {
            final MetricsComponent createdComponent = new Component(name);
            component = componentsRegistry.putIfAbsent(name, createdComponent);
            if (component == null) {
                component = createdComponent;
            }
        }
        return component;
    }

    /**
     * Registry for the Metrics objects created in the system.
     */
    private static final MetricRegistry METRICS_REGISTRY = new MetricRegistry();

    /**
     * Generates a name for a Metric from its component and feature.
     *
     * @param component component the metric is defined in
     * @param feature feature the metric is defined in
     * @param metricName local name of the metric
     *
     * @return full name of the metric
     */
    public static String generateName(final MetricsComponent component,
                                      final MetricsFeature feature,
                                      final String metricName) {
        return MetricRegistry.name(component.getName(),
                                   feature.getName(),
                                   metricName);
    }

    /**
     * Creates a Counter metric.
     *
     * @param component component the Counter is defined in
     * @param feature feature the Counter is defined in
     * @param metricName local name of the metric
     * @return Counter Meteric
     */
    public static Counter createCounter(final MetricsComponent component,
                                        final MetricsFeature feature,
                                        final String metricName) {
        final String name = generateName(component, feature, metricName);
        return METRICS_REGISTRY.counter(name);
    }

    /**
     * Creates a Histogram metric.
     *
     * @param component component the Histogram is defined in
     * @param feature feature the Histogram is defined in
     * @param metricName local name of the metric
     * @return Histogram Metric
     */
    public static Histogram createHistogram(final MetricsComponent component,
                                            final MetricsFeature feature,
                                            final String metricName) {
        final String name = generateName(component, feature, metricName);
        return METRICS_REGISTRY.histogram(name);
    }

    /**
     * Creates a Timer metric.
     *
     * @param component component the Timer is defined in
     * @param feature feature the Timeer is defined in
     * @param metricName local name of the metric
     * @return Timer Metric
     */
    public static Timer createTimer(final MetricsComponent component,
                                    final MetricsFeature feature,
                                    final String metricName) {
        final String name = generateName(component, feature, metricName);
        return METRICS_REGISTRY.timer(name);
    }

    /**
     * Creates a Meter metric.
     *
     * @param component component the Meter is defined in
     * @param feature feature the Meter is defined in
     * @param metricName local name of the metric
     * @return Meter Metric
     */
    public static Meter createMeter(final MetricsComponent component,
                                    final MetricsFeature feature,
                                    final String metricName) {
        final String name = generateName(component, feature, metricName);
        return METRICS_REGISTRY.meter(name);
    }

    /**
     * Registers an already created Metric.  This is used for situation where a
     * caller needs to allocate its own Metric, but still register it with the
     * system.
     *
     * @param component component the Metric is defined in
     * @param feature feature the metric is defined in
     * @param metricName local name of the metric
     * @param metric Metric to register
     */
    public static void registerMetric(final MetricsComponent component,
                                      final MetricsFeature feature,
                                      final String metricName,
                                      final Metric metric) {
        final String name = generateName(component, feature, metricName);
        METRICS_REGISTRY.register(name, metric);
    }

    /**
     * Fetches the existing Timers.
     *
     * @param filter filter to use to select Timers
     * @return a map of the Timers that match the filter, with the key as the
     *         name String to the Timer.
     */
    public static Map<String, Timer> getTimers(final MetricFilter filter) {
        return METRICS_REGISTRY.getTimers(filter);
    }

    /**
     * Fetches the existing Gauges.
     *
     * @param filter filter to use to select Gauges
     * @return a map of the Gauges that match the filter, with the key as the
     *         name String to the Gauge.
     */
    @SuppressWarnings("rawtypes")
    public static Map<String, Gauge> getGauges(final MetricFilter filter) {
        return METRICS_REGISTRY.getGauges(filter);
    }

    /**
     * Fetches the existing Counters.
     *
     * @param filter filter to use to select Counters
     * @return a map of the Counters that match the filter, with the key as the
     *         name String to the Counter.
     */
    public static Map<String, Counter> getCounters(final MetricFilter filter) {
        return METRICS_REGISTRY.getCounters(filter);
    }

    /**
     * Fetches the existing Meters.
     *
     * @param filter filter to use to select Meters
     * @return a map of the Meters that match the filter, with the key as the
     *         name String to the Meter.
     */
    public static Map<String, Meter> getMeters(final MetricFilter filter) {
        return METRICS_REGISTRY.getMeters(filter);
    }

    /**
     * Fetches the existing Histograms.
     *
     * @param filter filter to use to select Histograms
     * @return a map of the Histograms that match the filter, with the key as the
     *         name String to the Histogram.
     */
    public static Map<String, Histogram> getHistograms(final MetricFilter filter) {
        return METRICS_REGISTRY.getHistograms(filter);
    }

    /**
     * Removes all Metrics that match a given filter.
     *
     * @param filter filter to use to select the Metrics to remove.
     */
    public static void removeMatching(final MetricFilter filter) {
        METRICS_REGISTRY.removeMatching(filter);
    }
}

