package ru.yandex.webmaster3.monitoring.common;

import ru.yandex.webmaster3.storage.util.yt.YtException;
import ru.yandex.webmaster3.storage.util.yt.YtPath;
import ru.yandex.webmaster3.storage.util.yt.YtService;

import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Created by leonidrom on 19/07/2017.
 */
public class YtQueueUtils {
    private static final Pattern UNIX_TIMESTAMP_PATTERN = Pattern.compile("(\\d{10})$");
    private static final Pattern JAVA_TIMESTAMP_PATTERN = Pattern.compile("(\\d{13})$");

    public static Function<String, Long> byUnixTimestamp(final Pattern pattern) {
        return tableName -> {
            Matcher matcher = pattern.matcher(tableName);
            return matcher.find()? Long.parseLong(matcher.group(1)) * 1000 : 0;
        };
    }

    public static Function<String, Long> UNIX_TIMESTAMP_EXTRACTOR = byUnixTimestamp(UNIX_TIMESTAMP_PATTERN);

    public static Function<String, Long> JAVA_TIMESTAMP_EXTRACTOR = tableName -> {
        Matcher matcher = JAVA_TIMESTAMP_PATTERN.matcher(tableName);
        return matcher.find()? Long.parseLong(matcher.group(1)) : 0;
    };

    public static Predicate<String> ALL_TABLES_FILTER = t -> true;

    public static QueueStats getQueueStats(YtService ytService, YtPath tablesPath,
                                    Predicate<String> tablesFilter, Function<String, Long> timestampExtractor)
            throws YtException, InterruptedException {

        QueueStats stats = new QueueStats();
        ytService.withoutTransactionQuery(cypressService -> {
            List<String> tables = cypressService.list(tablesPath)
                    .stream()
                    .map(YtPath::getName)
                    .filter(tablesFilter)
                    .collect(Collectors.toList());

            if (tables.isEmpty()) {
                return true;
            }

            LongSummaryStatistics lss = tables.stream().collect(Collectors.summarizingLong(timestampExtractor::apply));
            stats.tablesCount = tables.size();
            stats.maxAgeInMillis = System.currentTimeMillis() - lss.getMin();
            stats.minAgeInMillis = System.currentTimeMillis() - lss.getMax();

            return true;
        });

        return stats;
    }    

    public static class QueueStats {
        public int tablesCount;
        public long maxAgeInMillis;
        public long minAgeInMillis;
    }
}
