package eu.dnetlib.metrics;

/**
 * Created by Alessia Bardi on 2019-06-21.
 *
 * @author Alessia Bardi
 */

import java.time.Duration;

import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.micrometer.spring.autoconfigure.export.prometheus.PrometheusProperties;
import io.prometheus.client.CollectorRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PrometheusEndpointConfig {

	@Bean
	public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig config, CollectorRegistry collectorRegistry,
			Clock clock) {
		PrometheusMeterRegistry pr =  new PrometheusMeterRegistry(config, collectorRegistry, clock);
		threadMetrics().bindTo(pr);
		memoryMetrics().bindTo(pr);
		jvmgcMetrics().bindTo(pr);
		return pr;
	}

	@Bean
	public Clock micrometerClock() {
		return Clock.SYSTEM;
	}

	@Bean
	public PrometheusConfig prometheusConfig(PrometheusProperties props) {
		return new DefaultPrometheusConfig(props);
	}

	@Bean
	public PrometheusProperties prometheusProperties(){
		return new PrometheusProperties();
	}

	@Bean
	public CollectorRegistry collectorRegistry() {
		return new CollectorRegistry(true);
	}

	@Bean
	public JvmThreadMetrics threadMetrics(){
		return new JvmThreadMetrics();}

	@Bean
	public JvmMemoryMetrics memoryMetrics(){
		return new JvmMemoryMetrics();
	}

	@Bean
	public JvmGcMetrics jvmgcMetrics(){
		return new JvmGcMetrics();
	}


	private class DefaultPrometheusConfig implements PrometheusConfig {
		private final PrometheusProperties props;
		private final PrometheusConfig defaults = k -> null;

		private DefaultPrometheusConfig(PrometheusProperties props) {
			this.props = props;
		}

		@Override
		public String get(String k) {
			return null;
		}

		@Override
		public boolean descriptions() {
			return props.isDescriptions();
		}

		@Override
		public Duration step() {
			return props.getStep() == null ? defaults.step() : props.getStep();
		}
	}
}
