package com.atlassian.bitbucket.mesh.metrics;

import com.atlassian.util.profiling.Metrics;
import com.atlassian.util.profiling.StrategiesRegistry;
import com.atlassian.util.profiling.Ticker;
import com.atlassian.util.profiling.strategy.MetricStrategy;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.binder.MeterBinder;

import javax.annotation.Nonnull;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

import static com.atlassian.bitbucket.mesh.metrics.MetricsConstants.PREFIX_OPERATION;
import static java.util.Objects.requireNonNull;

public class AtlassianProfilingIntegration implements MeterBinder {

    @Override
    public void bindTo(@Nonnull MeterRegistry registry) {
        //Integrate with atlassian-profiling
        StrategiesRegistry.addMetricStrategy(new MicrometerMetricsStrategy(registry));
        //Enable metrics collection in atlassian-profiling
        Metrics.getConfiguration().setEnabled(true);
    }

    private static class MicrometerMetricsStrategy implements MetricStrategy {

        private final MeterRegistry registry;

        MicrometerMetricsStrategy(MeterRegistry registry) {
            this.registry = registry;
        }

        @Nonnull
        @Override
        public Ticker startTimer(@Nonnull String metricName) {
            Timer.Sample sample = Timer.start(registry);
            return () -> sample.stop(registry.timer(PREFIX_OPERATION + metricName));
        }

        @Override
        public void updateHistogram(@Nonnull String metricName, long value) {
            registry.summary(PREFIX_OPERATION + metricName).record(value);
        }

        @Override
        public void updateTimer(@Nonnull String metricName, long time, @Nonnull TimeUnit timeUnit) {
            requireNonNull(metricName, "metricName");
            requireNonNull(timeUnit, "timeUnit");

            registry.timer(PREFIX_OPERATION + metricName).record(Duration.ofNanos(timeUnit.toNanos(time)));
        }
    }
}
