package io.symphonia.lambda.metrics;

import io.symphonia.lambda.annotations.CloudwatchLogGroup;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractMetricFiltersMojo extends AbstractMojo {
    public static Map<String, String> COMPLETE_FILTER_PATTERN_MAP = new HashMap<String, String>() {{
        put("COUNTER", "[datetime,request_id,level=METRIC,logger,type_label,type=COUNTER,name_label,name=\"%s\",count_label,count]");
        put("GAUGE", "[datetime,request_id,level=METRIC,logger,type_label,type=GAUGE,name_label,name=\"%s\",value_label,value]");
        put("METER", "[datetime,request_id,level=METRIC,logger,type_label,type=METER,name_label,name=\"%s\",count_label,count,mean_rate_label,mean_rate,...]");
        put("HISTOGRAM", "[datetime,request_id,level=METRIC,logger,type_label,type=HISTOGRAM,name_label,name=\"%s\",count_label,count,min_label,min,max_label,max,mean_label,mean,stddev_label,stddev,median_label,median,p75_label,p75,p95_label,p95,p98_label,p98,p99_label,p99,p999_label,p999]");
        put("TIMER", "[datetime,request_id,level=METRIC,logger,type_label,type=TIMER,name_label,name=\"%s\",count_label,count,min_label,min,max_label,max,mean_label,mean,stddev_label,stddev,median_label,median,p75_label,p75,p95_label,p95,p98_label,p98,p99_label,p99,p999_label,p999,mean_rate_label,mean_rate,...]");
    }};
    public static Map<String, List<String>> COMPLETE_METRIC_VALUE_MAP = new HashMap<String, List<String>>() {{
        put("COUNTER", Collections.singletonList("count"));
        put("GAUGE", Collections.singletonList("value"));
        put("METER", Arrays.asList("count", "mean_rate", "m1", "m5", "m15"));
        put("HISTOGRAM", Arrays.asList("count", "min", "max", "mean", "stddev", "median",
                "p75", "p95", "p98", "p99", "p999"));
        put("TIMER", Arrays.asList("count", "min", "max", "mean", "stddev", "median",
                "p75", "p95", "p98", "p99", "p999", "mean_rate", "m1", "m5", "m15"));
    }};
    public static Map<String, List<String>> REDUCED_METRIC_VALUE_MAP = new HashMap<String, List<String>>() {{
        put("COUNTER", Collections.singletonList("count"));
        put("GAUGE", Collections.singletonList("value"));
        put("METER", Collections.singletonList("mean_rate"));
        put("HISTOGRAM", Arrays.asList("min", "max", "mean", "p75", "p99", "p999"));
        put("TIMER", Arrays.asList("min", "max", "mean", "p75", "p99", "p999", "mean_rate"));
    }};

    @Parameter(required = false)
    public Map<String, String> filterPatternMap = COMPLETE_FILTER_PATTERN_MAP;

    @Parameter(required = false)
    public Map<String, List<String>> metricValueMap = COMPLETE_METRIC_VALUE_MAP;

    @Parameter(required = false)
    private String cloudwatchLogGroupName;

    protected List<MetricFilter> getMetricFilters(Map<String, Field> metricFields) {
        List<MetricFilter> metricFilters = new ArrayList<>();
        for (Map.Entry<String, Field> metricFieldEntry : metricFields.entrySet()) {
            String fullMetricName = metricFieldEntry.getKey();
            Field metricField = metricFieldEntry.getValue();
            String metricType = metricField.getType().getSimpleName().toUpperCase();

            if (!filterPatternMap.keySet().contains(metricType)) {
                getLog().warn(String.format("Skipping metric field [%s] with unsupported type [%s]",
                        metricField.getName(), metricType));
                break;
            }

            CloudwatchLogGroup logGroupAnnotation = metricField.getDeclaringClass().getAnnotation(CloudwatchLogGroup.class);
            String logGroup = logGroupAnnotation != null && !logGroupAnnotation.value().isEmpty() ?
                    logGroupAnnotation.value() : cloudwatchLogGroupName;

            if (logGroup == null || logGroup.isEmpty()) {
                getLog().warn(String.format("No log group found for metric field [%s].", metricField.getName()));
                break;
            }

            // TODO: Merge w/ default values, so overriding doesn't require complete respecification
            String filterPatternFormat = filterPatternMap.get(metricType);
            List<String> metricValues = metricValueMap.get(metricType);


            for (String metricValue : metricValues) {
                metricFilters.add(new MetricFilter(logGroup, fullMetricName, filterPatternFormat, metricValue));
            }
        }
        return metricFilters;
    }
}

@@ -449,16 +449,17 @@
 tMojo %7B%0A
+%0A
     publ
@@ -655,32 +655,53 @@
 bel,name=%5C%22%25s%5C%22,
+%22 +%0A                %22
 count_label,coun
@@ -814,16 +814,37 @@
 =%5C%22%25s%5C%22,
+%22 +%0A                %22
 value_la
@@ -957,32 +957,53 @@
 bel,name=%5C%22%25s%5C%22,
+%22 +%0A                %22
 count_label,coun
@@ -1146,32 +1146,53 @@
 bel,name=%5C%22%25s%5C%22,
+%22 +%0A                %22
 count_label,coun
@@ -1262,32 +1262,53 @@
 ev,median_label,
+%22 +%0A                %22
 median,p75_label
@@ -1482,16 +1482,37 @@
 =%5C%22%25s%5C%22,
+%22 +%0A                %22
 count_la
@@ -1598,16 +1598,37 @@
 n_label,
+%22 +%0A                %22
 median,p
@@ -1706,32 +1706,53 @@
 mean_rate_label,
+%22 +%0A                %22
 mean_rate,...%5D%22)
@@ -1753,32 +1753,33 @@
 ...%5D%22);%0A    %7D%7D;%0A
+%0A
     public stati
@@ -2393,16 +2393,17 @@
     %7D%7D;%0A
+%0A
     publ
@@ -3181,22 +3181,12 @@
 e;%0A%0A
+
     
-protected 
 List

Reformat constants