package com.atlassian.bitbucket.mesh.metrics;

import com.atlassian.bitbucket.mesh.throttle.ThrottleService;
import com.atlassian.bitbucket.mesh.throttle.ThrottledResource;
import com.atlassian.bitbucket.mesh.throttle.TicketSummary;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.binder.MeterBinder;

import javax.annotation.Nonnull;

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

/**
 * Configures {@link ThrottleService throttling} related metrics.
 */
public class ThrottlingMetrics implements MeterBinder {

    private final ThrottleService throttleService;

    public ThrottlingMetrics(@Nonnull ThrottleService throttleService) {
        this.throttleService = requireNonNull(throttleService, "throttleService");
    }

    @Override
    public void bindTo(@Nonnull MeterRegistry registry) {
        for (TicketSummary summary : throttleService.getSummaries()) {
            ThrottledResource resource = summary.getResource();
            String prefix = PREFIX_THROTTLING;
            Tags tags = Tags.of(TAG_THROTTLED_RESOURCE, resource.getId());
            Gauge.builder(prefix + "tickets.available", () -> throttleService.getSummary(resource).getAvailable())
                    .description("The number of currently available " + resource.getId() + " throttling tickets")
                    .tags(tags)
                    .register(registry);
            Gauge.builder(prefix + "tickets.total", () -> throttleService.getSummary(resource).getTotal())
                    .description("The total number of " + resource.getId() + " throttling tickets")
                    .tags(tags)
                    .register(registry);
            Gauge.builder(prefix + "threads.queued", () -> throttleService.getSummary(resource).getQueuedRequests())
                    .description("The number of threads currently waiting for a " + resource.getId() + " ticket")
                    .tags(tags)
                    .register(registry);
            Gauge.builder(prefix + "tickets.used", () -> throttleService.getSummary(resource).getUsed())
                    .description("The number of " + resource.getId() + " throttling tickets currently in use")
                    .tags(tags)
                    .register(registry);
        }
    }
}
