package ru.yandex.webmaster3.core.solomon.metric;

import org.joda.time.Duration;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;

/**
 * @author avhaliullin
 */
public class SolomonTimerConfiguration extends SolomonMetricConfiguration {
    public static final NavigableSet<Duration> DEFAULT_BUCKETS;

    static {
        NavigableSet<Duration> buckets = new TreeSet<>();
        buckets.add(Duration.millis(150));
        buckets.add(Duration.millis(250));
        buckets.add(Duration.millis(500));
        buckets.add(Duration.millis(1100));
        buckets.add(Duration.millis(1700));
        buckets.add(Duration.millis(2600));
        buckets.add(Duration.millis(3600));
        buckets.add(Duration.millis(6100));
        buckets.add(Duration.millis(10100));
        buckets.add(Duration.millis(15100));
        buckets.add(Duration.millis(30000));
        DEFAULT_BUCKETS = Collections.unmodifiableNavigableSet(buckets);
    }

    private Collection<Duration> buckets = new TreeSet<>(DEFAULT_BUCKETS);
    private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
    private String durationIndicatorName;
    private Set<Set<String>> durationGroupBy;

    /**
     * Единицы времени, в которой корзины будут отгружаться в соломон.
     */
    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }

    /**
     * Список корзин, по которым нужно раскладывать времена
     */
    public void setBuckets(Collection<Duration> buckets) {
        this.buckets = buckets;
    }

    public Collection<Duration> getBuckets() {
        return buckets;
    }

    public TimeUnit getTimeUnit() {
        return timeUnit;
    }

    /*
        Для процессов, у которых мы измеряем время - существует как минимум две очевидные метрики,
        которые можно отобразить в соломоне:
        1. Распределение времен ответов по корзинкам
        2. Совокупное время работы процессов (в простом случае - потребление секундоядер) на единицу времени

        Методы, лежащие ниже, позволяют настроить выгрузку второй метрики в соломон - для этого достаточно указать
        отдельный индикатор, и отдельные группировки, которые нужны для этой метрики
     */

    public void setDurationIndicatorName(String durationIndicatorName) {
        this.durationIndicatorName = durationIndicatorName;
    }

    public String getDurationIndicatorName() {
        return durationIndicatorName;
    }

    public void setDurationGroupBy(List<String> groupBy) {
        this.durationGroupBy = parseGroupBy(groupBy);
    }

    public Set<Set<String>> getDurationGroupBy() {
        return durationGroupBy;
    }
}
