// Path: src/main/java/com/statful/utils/Pair.java
// public final class Pair<L, R> {
// 
//     /**
//      * Left element of the Pair
//      */
//     private L left;
//     /**
//      * Right element of the Pair
//      */
//     private R right;
// 
//     /**
//      * Pair constructor
//      *
//      * @param left  element of the pair
//      * @param right element of the pair
//      */
//     public Pair(final L left, final R right) {
//         this.left = left;
//         this.right = right;
//     }
// 
//     /**
//      * @return gets the value of the left element
//      */
//     public L getLeft() {
//         return left;
//     }
// 
//     /**
//      * @return gets the value of the right element
//      */
//     public R getRight() {
//         return right;
//     }
// 
//     @Override
//     public String toString() {
//         return "Pair{" + "left=" + left + ", right=" + right + '}';
//     }
// 
//     @Override
//     public boolean equals(final Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
//         Pair<?, ?> pair = (Pair<?, ?>) o;
//         return Objects.equals(left, pair.left)
//                 && Objects.equals(right, pair.right);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(left, right);
//     }
// }


import com.google.common.collect.Lists;
import com.statful.utils.Pair;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.metrics.MetricsOptions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
package com.statful.client;




/**
 * Vert.x Statful metrics configuration
 */
public class StatfulMetricsOptions extends MetricsOptions {

    /**
     * Default Statful host constant
     */
    private static final String DEFAULT_HOST = "api.statful.com";

    /**
     * Default port Statful port
     */
    private static final int DEFAULT_PORT = 443;

    /**
     * Default value for a secure connection (https)
     */
    private static final Boolean DEFAULT_SECURE = true;

    /**
     * Default timeout value to be used by the client to connect to Statful
     */
    private static final int DEFAULT_TIMEOUT = 2000;

    /**
     * Default value for dry run configuration
     */
    private static final Boolean DEFAULT_DRY_RUN = false;

    /**
     * Maximum value allowed for the sample rate
     */
    public static final Integer MAX_SAMPLE_RATE = 100;

    /**
     * Minimum value allowed for the sample rate
     */
    private static final Integer MIN_SAMPLE_RATE = 1;

    /**
     * Default sample rate to applied to all metrics
     */
    private static final Integer DEFAULT_SAMPLE_RATE = MAX_SAMPLE_RATE;

    /**
     * Default namespace to be applied in all metrics
     */
    private static final String DEFAULT_NAMESPACE = "application";

    /**
     * Default size of elements that the buffer can old before flushing
     */
    private static final int DEFAULT_FLUSH_SIZE = 10;

    /**
     * Default flush interval at which metrics are sent
     */
    private static final long DEFAULT_FLUSH_INTERVAL = 30000;

    /**
     * Default transport definition
     */
    private static final Transport DEFAULT_TRANSPORT = Transport.HTTP;

    /**
     * Default aggregations to be applied for Timer metrics
     */
    private static final List<Aggregation> DEFAULT_TIMER_AGGREGATIONS = Lists.newArrayList(Aggregation.AVG, Aggregation.P90, Aggregation.COUNT);

    /**
     * Default aggregations to be applied for Gauge metrics
     */
    private static final List<Aggregation> DEFAULT_GAUGE_AGGREGATIONS = Lists.newArrayList(Aggregation.LAST, Aggregation.MAX, Aggregation.AVG);

    /**
     * Default aggregations to be applied for Counter metrics
     */
    private static final List<Aggregation> DEFAULT_COUNTER_AGGREGATIONS = Lists.newArrayList(Aggregation.COUNT, Aggregation.SUM);

    /**
     * Default value for Aggregations Frequency for metrics
     */
    private static final AggregationFreq DEFAULT_FREQUENCY = AggregationFreq.FREQ_10;

    /**
     * Default value for gauge reporting in milliseconds
     */
    private static final long DEFAULT_GAUGE_REPORTING_INTERVAL = 5000;

    /**
     * Default to enable/disable all the available collectors
     */
    private static final boolean DEFAULT_METRIC_COLLECTION = false;

    /**
     * Default maximum theoretical buffer size that holds metrics in memory between flushes
     */
    private static final int DEFAULT_MAX_BUFFER_SIZE = 5000;

    /**
     * Default Http path to store metrics
     */
    private static final String DEFAULT_HTTP_METRICS_PATH = "/tel/v2.0/metrics";

    /**
     * Statful host, default value {@value #DEFAULT_HOST}
     */
    private String host = DEFAULT_HOST;

    /**
     * Optional Statful default port, default value {@value #DEFAULT_PORT}
     */
    private int port = DEFAULT_PORT;

    /**
     * Defines the transport to be used to set which type of transport will be used to push the metrics.
     */
    private Transport transport = DEFAULT_TRANSPORT;

    /**
     * Defines whether to use https or not, default value {@value #DEFAULT_SECURE}
     */
    private boolean secure = DEFAULT_SECURE;

    /**
     * Defines timeout for the client reporter (http / tcp transports), default value {@value #DEFAULT_TIMEOUT}
     */
    private int timeout = DEFAULT_TIMEOUT;

    /**
     * Application token, to be used by the http transport
     */
    private String token;

    /**
     * Optional value to map to an extra TAG defining the application
     */
    private String app;

    /**
     * Optional configuration to not send any metrics when flushing the buffer, default value {@value #DEFAULT_DRY_RUN}
     */
    private boolean dryrun = DEFAULT_DRY_RUN;

    /**
     * Tags to be applied, default value {@link Collections#emptyList()}
     */
// Path: src/main/java/com/statful/utils/Pair.java
// public final class Pair<L, R> {
// 
//     /**
//      * Left element of the Pair
//      */
//     private L left;
//     /**
//      * Right element of the Pair
//      */
//     private R right;
// 
//     /**
//      * Pair constructor
//      *
//      * @param left  element of the pair
//      * @param right element of the pair
//      */
//     public Pair(final L left, final R right) {
//         this.left = left;
//         this.right = right;
//     }
// 
//     /**
//      * @return gets the value of the left element
//      */
//     public L getLeft() {
//         return left;
//     }
// 
//     /**
//      * @return gets the value of the right element
//      */
//     public R getRight() {
//         return right;
//     }
// 
//     @Override
//     public String toString() {
//         return "Pair{" + "left=" + left + ", right=" + right + '}';
//     }
// 
//     @Override
//     public boolean equals(final Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
//         Pair<?, ?> pair = (Pair<?, ?>) o;
//         return Objects.equals(left, pair.left)
//                 && Objects.equals(right, pair.right);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(left, right);
//     }
// }


// Path: src/main/java/com/statful/client/StatfulMetricsOptions.java
import com.google.common.collect.Lists;
import com.statful.utils.Pair;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.metrics.MetricsOptions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;

package com.statful.client;




/**
 * Vert.x Statful metrics configuration
 */
public class StatfulMetricsOptions extends MetricsOptions {

    /**
     * Default Statful host constant
     */
    private static final String DEFAULT_HOST = "api.statful.com";

    /**
     * Default port Statful port
     */
    private static final int DEFAULT_PORT = 443;

    /**
     * Default value for a secure connection (https)
     */
    private static final Boolean DEFAULT_SECURE = true;

    /**
     * Default timeout value to be used by the client to connect to Statful
     */
    private static final int DEFAULT_TIMEOUT = 2000;

    /**
     * Default value for dry run configuration
     */
    private static final Boolean DEFAULT_DRY_RUN = false;

    /**
     * Maximum value allowed for the sample rate
     */
    public static final Integer MAX_SAMPLE_RATE = 100;

    /**
     * Minimum value allowed for the sample rate
     */
    private static final Integer MIN_SAMPLE_RATE = 1;

    /**
     * Default sample rate to applied to all metrics
     */
    private static final Integer DEFAULT_SAMPLE_RATE = MAX_SAMPLE_RATE;

    /**
     * Default namespace to be applied in all metrics
     */
    private static final String DEFAULT_NAMESPACE = "application";

    /**
     * Default size of elements that the buffer can old before flushing
     */
    private static final int DEFAULT_FLUSH_SIZE = 10;

    /**
     * Default flush interval at which metrics are sent
     */
    private static final long DEFAULT_FLUSH_INTERVAL = 30000;

    /**
     * Default transport definition
     */
    private static final Transport DEFAULT_TRANSPORT = Transport.HTTP;

    /**
     * Default aggregations to be applied for Timer metrics
     */
    private static final List<Aggregation> DEFAULT_TIMER_AGGREGATIONS = Lists.newArrayList(Aggregation.AVG, Aggregation.P90, Aggregation.COUNT);

    /**
     * Default aggregations to be applied for Gauge metrics
     */
    private static final List<Aggregation> DEFAULT_GAUGE_AGGREGATIONS = Lists.newArrayList(Aggregation.LAST, Aggregation.MAX, Aggregation.AVG);

    /**
     * Default aggregations to be applied for Counter metrics
     */
    private static final List<Aggregation> DEFAULT_COUNTER_AGGREGATIONS = Lists.newArrayList(Aggregation.COUNT, Aggregation.SUM);

    /**
     * Default value for Aggregations Frequency for metrics
     */
    private static final AggregationFreq DEFAULT_FREQUENCY = AggregationFreq.FREQ_10;

    /**
     * Default value for gauge reporting in milliseconds
     */
    private static final long DEFAULT_GAUGE_REPORTING_INTERVAL = 5000;

    /**
     * Default to enable/disable all the available collectors
     */
    private static final boolean DEFAULT_METRIC_COLLECTION = false;

    /**
     * Default maximum theoretical buffer size that holds metrics in memory between flushes
     */
    private static final int DEFAULT_MAX_BUFFER_SIZE = 5000;

    /**
     * Default Http path to store metrics
     */
    private static final String DEFAULT_HTTP_METRICS_PATH = "/tel/v2.0/metrics";

    /**
     * Statful host, default value {@value #DEFAULT_HOST}
     */
    private String host = DEFAULT_HOST;

    /**
     * Optional Statful default port, default value {@value #DEFAULT_PORT}
     */
    private int port = DEFAULT_PORT;

    /**
     * Defines the transport to be used to set which type of transport will be used to push the metrics.
     */
    private Transport transport = DEFAULT_TRANSPORT;

    /**
     * Defines whether to use https or not, default value {@value #DEFAULT_SECURE}
     */
    private boolean secure = DEFAULT_SECURE;

    /**
     * Defines timeout for the client reporter (http / tcp transports), default value {@value #DEFAULT_TIMEOUT}
     */
    private int timeout = DEFAULT_TIMEOUT;

    /**
     * Application token, to be used by the http transport
     */
    private String token;

    /**
     * Optional value to map to an extra TAG defining the application
     */
    private String app;

    /**
     * Optional configuration to not send any metrics when flushing the buffer, default value {@value #DEFAULT_DRY_RUN}
     */
    private boolean dryrun = DEFAULT_DRY_RUN;

    /**
     * Tags to be applied, default value {@link Collections#emptyList()}
     */
    private List<Pair<String, String>> tags = Collections.emptyList();