/**
 * Copyright 2017 Pivotal Software, Inc.
 * <p>
 * Licensed 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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 io.micrometer.datadog;

import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Statistic;

import java.util.*;

/**
 * @author Jon Schneider
 */
class DatadogMetricMetadata {
    private final Meter.Id id;
    private final String type;
    private final String overrideBaseUnit;
    private final boolean descriptionsEnabled;

    // Datadog rejects anything not on this list: https://docs.datadoghq.com/units/
    private final Set<String> unitWhitelist = new HashSet<>(Arrays.asList(
        "bit", "byte", "kilobyte", "megabyte", "gigabyte", "terabyte", "petabyte", "exobyte",
        "microsecond", "millisecond", "second", "minute", "hour", "day", "week", "nanosecond",
        "fraction", "percent", "percent_nano", "apdex",
        "connection", "request", "packet", "segment", "response", "message", "payload", "timeout", "datagram", "route", "session",
        "process", "core", "thread", "host", "node", "fault", "service", "instance", "cpu",
        "file", "inode", "sector", "block",
        "buffer", "error", "read", "write", "occurrence", "event", "time", "unit", "operation", "item", "task", "worker", "resource",
        "email", "sample", "stage", "monitor", "location", "check", "attempt", "device", "update", "method", "job", "container",
        "table", "index", "lock", "transaction", "query", "row", "key", "command", "offset", "record", "object", "cursor", "assertion", "scan", "document", "shard", "flush", "merge", "refresh", "fetch", "column", "commit", "wait", "ticket", "question",
        "hit", "miss", "eviction", "get", "set",
        "dollar", "cent",
        "page", "split",
        "hertz", "kilohertz", "megahertz", "gigahertz",
        "entry"));

    private final Map<String, String> pluralizedUnitMapping = new HashMap<>();

    DatadogMetricMetadata(Meter.Id id, Statistic statistic, boolean descriptionsEnabled, String overrideBaseUnit) {
        this.id = id;
        this.descriptionsEnabled = descriptionsEnabled;
        this.overrideBaseUnit = overrideBaseUnit;

        this.unitWhitelist.forEach(unit -> pluralizedUnitMapping.put(unit + "s", unit));
        this.pluralizedUnitMapping.put("indices", "index");
        this.pluralizedUnitMapping.put("indexes", "index");

        switch (statistic) {
            case Count:
            case Total:
            case TotalTime:
                this.type = "count";
                break;
            default:
                this.type = "gauge";
        }
    }

    String editMetadataBody() {
        String body = "{\"type\":\"" + type + "\"";

        String baseUnit = overrideBaseUnit != null ? overrideBaseUnit : id.getBaseUnit();
        if (baseUnit != null) {
            String whitelistedBaseUnit = unitWhitelist.contains(baseUnit) ? baseUnit :
                pluralizedUnitMapping.get(baseUnit);

            if(whitelistedBaseUnit != null) {
                body += ",\"unit\":\"" + whitelistedBaseUnit + "\"";
            }
        }

        if (descriptionsEnabled && id.getDescription() != null) {
            body += ",\"description\":\"" + id.getDescription() + "\"";
        }

        body += "}";

        return body;
    }
}

@@ -820,160 +820,8 @@
 ta %7B
-%0A    private final Meter.Id id;%0A    private final String type;%0A    private final String overrideBaseUnit;%0A    private final boolean descriptionsEnabled;
 %0A%0A  
@@ -910,24 +910,31 @@
     private 
+static 
 final Set%3CSt
@@ -943,24 +943,53 @@
 ng%3E 
-unitWhitelist = 
+UNIT_WHITELIST = Collections.unmodifiableSet(
 new 
@@ -2214,16 +2214,17 @@
 entry%22))
+)
 ;%0A%0A    p
@@ -2230,16 +2230,23 @@
 private 
+static 
 final Ma
@@ -2267,47 +2267,554 @@
 ng%3E 
-pluralizedUnitMapping = new HashMap%3C%3E()
+PLURALIZED_UNIT_MAPPING;%0A%0A    static %7B%0A        Map%3CString, String%3E pluralizedUnitMapping = new HashMap%3C%3E();%0A        UNIT_WHITELIST.forEach(unit -%3E pluralizedUnitMapping.put(unit + %22s%22, unit));%0A        pluralizedUnitMapping.put(%22indices%22, %22index%22);%0A        pluralizedUnitMapping.put(%22indexes%22, %22index%22);%0A        PLURALIZED_UNIT_MAPPING = Collections.unmodifiableMap(pluralizedUnitMapping);%0A    %7D%0A%0A    private final Meter.Id id;%0A    private final String type;%0A    private final String overrideBaseUnit;%0A    private final boolean descriptionsEnabled
 ;%0A%0A 
@@ -3061,218 +3061,8 @@
 t;%0A%0A
-        this.unitWhitelist.forEach(unit -%3E pluralizedUnitMapping.put(unit + %22s%22, unit));%0A        this.pluralizedUnitMapping.put(%22indices%22, %22index%22);%0A        this.pluralizedUnitMapping.put(%22indexes%22, %22index%22);%0A%0A
     
@@ -3549,21 +3549,22 @@
 t = 
-unitWhitelist
+UNIT_WHITELIST
 .con
@@ -3608,37 +3608,39 @@
         
-pluralizedUnitMapping
+PLURALIZED_UNIT_MAPPING
 .get(bas

Make unitWhitelist and pluralizedUnitMapping static