/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.bookkeeper.stats.prometheus;

import io.prometheus.client.Collector;
import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.Collector.MetricFamilySamples.Sample;
import io.prometheus.client.CollectorRegistry;

import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Map;

/**
 * Logic to write metrics in Prometheus text format.
 */
public class PrometheusTextFormatUtil {
    static void writeGauge(Writer w, String name, SimpleGauge<? extends Number> gauge) {
        // Example:
        // # TYPE bookie_storage_entries_count gauge
        // bookie_storage_entries_count 519
        try {
            w.append("# TYPE ").append(name).append(" gauge\n");
            w.append(name);
            writeLabels(w, gauge.getLabels());
            w.append(' ').append(gauge.getSample().toString()).append('\n');
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    static void writeCounter(Writer w, String name, LongAdderCounter counter) {
        // Example:
        // # TYPE jvm_threads_started_total counter
        // jvm_threads_started_total 59
        try {
            w.append("# TYPE ").append(name).append(" counter\n");
            w.append(name);
            writeLabels(w, counter.getLabels());
            w.append(' ').append(counter.get().toString()).append('\n');
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    static void writeOpStat(Writer w, String name, DataSketchesOpStatsLogger opStat) {
        // Example:
        // # TYPE bookie_journal_JOURNAL_ADD_ENTRY summary
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.5",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.75",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.95",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.99",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.999",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="0.9999",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY{success="false",quantile="1.0",} NaN
        // bookie_journal_JOURNAL_ADD_ENTRY_count{success="false",} 0.0
        // bookie_journal_JOURNAL_ADD_ENTRY_sum{success="false",} 0.0
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.5",} 1.706
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.75",} 1.89
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.95",} 2.121
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.99",} 10.708
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.999",} 10.902
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="0.9999",} 10.902
        // bookie_journal_JOURNAL_ADD_ENTRY{success="true",quantile="1.0",} 10.902
        // bookie_journal_JOURNAL_ADD_ENTRY_count{success="true",} 658.0
        // bookie_journal_JOURNAL_ADD_ENTRY_sum{success="true",} 1265.0800000000002
        try {
            w.append("# TYPE ").append(name).append(" summary\n");
            writeQuantile(w, opStat, name, false, 0.5);
            writeQuantile(w, opStat, name, false, 0.75);
            writeQuantile(w, opStat, name, false, 0.95);
            writeQuantile(w, opStat, name, false, 0.99);
            writeQuantile(w, opStat, name, false, 0.999);
            writeQuantile(w, opStat, name, false, 0.9999);
            writeQuantile(w, opStat, name, false, 1.0);
            writeCount(w, opStat, name, false);
            writeSum(w, opStat, name, false);

            writeQuantile(w, opStat, name, true, 0.5);
            writeQuantile(w, opStat, name, true, 0.75);
            writeQuantile(w, opStat, name, true, 0.95);
            writeQuantile(w, opStat, name, true, 0.99);
            writeQuantile(w, opStat, name, true, 0.999);
            writeQuantile(w, opStat, name, true, 0.9999);
            writeQuantile(w, opStat, name, true, 1.0);
            writeCount(w, opStat, name, true);
            writeSum(w, opStat, name, true);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void writeLabels(Writer w, Map<String, String> labels) throws IOException {
        if (labels.isEmpty()) {
            return;
        }

        w.append('{');
        writeLabelsNoBraces(w, labels);
        w.append('}');
    }

    private static void writeLabelsNoBraces(Writer w, Map<String, String> labels) throws IOException {
        if (labels.isEmpty()) {
            return;
        }

        boolean isFirst = true;
        for (Map.Entry<String, String> e : labels.entrySet()) {
            if (!isFirst) {
                w.append(',');
            }
            isFirst = false;
            w.append(e.getKey())
                    .append("=\"")
                    .append(e.getValue())
                    .append('"');
        }
    }

    private static void writeQuantile(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success,
            double quantile) throws IOException {
        w.append(name)
                .append("{success=\"").append(success.toString())
                .append("\",quantile=\"").append(Double.toString(quantile))
                .append("\", ");
        writeLabelsNoBraces(w, opStat.getLabels());
        w.append("} ")
                .append(Double.toString(opStat.getQuantileValue(success, quantile))).append('\n');
    }

    private static void writeCount(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
            throws IOException {
        w.append(name).append("_count{success=\"").append(success.toString()).append("\", ");
        writeLabelsNoBraces(w, opStat.getLabels());
        w.append("\"} ")
                .append(Long.toString(opStat.getCount(success))).append('\n');
    }

    private static void writeSum(Writer w, DataSketchesOpStatsLogger opStat, String name, Boolean success)
            throws IOException {
        w.append(name).append("_sum{success=\"").append(success.toString()).append("\", ");
        writeLabelsNoBraces(w, opStat.getLabels());
        w.append("\"} ")
                .append(Double.toString(opStat.getSum(success))).append('\n');
    }

    static void writeMetricsCollectedByPrometheusClient(Writer w, CollectorRegistry registry) throws IOException {
        Enumeration<MetricFamilySamples> metricFamilySamples = registry.metricFamilySamples();
        while (metricFamilySamples.hasMoreElements()) {
            MetricFamilySamples metricFamily = metricFamilySamples.nextElement();

            for (int i = 0; i < metricFamily.samples.size(); i++) {
                Sample sample = metricFamily.samples.get(i);
                w.write(sample.name);
                w.write('{');
                for (int j = 0; j < sample.labelNames.size(); j++) {
                    if (j != 0) {
                        w.write(", ");
                    }
                    w.write(sample.labelNames.get(j));
                    w.write("=\"");
                    w.write(sample.labelValues.get(j));
                    w.write('"');
                }

                w.write("} ");
                w.write(Collector.doubleToGoString(sample.value));
                w.write('\n');
            }
        }
    }
}
