/**
 * 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.wavefront;

import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.core.instrument.util.StringEscapeUtils;
import io.micrometer.core.lang.Nullable;

public class WavefrontNamingConvention implements NamingConvention {
    private final NamingConvention delegate;

    @Nullable
    private String namePrefix;

    public WavefrontNamingConvention(@Nullable String namePrefix) {
        this(namePrefix, NamingConvention.dot);
    }

    public WavefrontNamingConvention(@Nullable String namePrefix, NamingConvention delegate) {
        this.delegate = delegate;
        this.namePrefix = (namePrefix != null && namePrefix.isEmpty()) ? null : namePrefix;
    }

    /**
     * Valid characters are: a-z, A-Z, 0-9, hyphen ("-"), underscore ("_"), dot ("."). Forward slash ("/") and comma
     * (",") are allowed if metricName is enclosed in double quotes.
     */
    @Override
    public String name(String name, Meter.Type type, @Nullable String baseUnit) {
        String sanitizedName = delegate.name(name, type, baseUnit).replaceAll("[^a-zA-Z0-9\\-_\\./,]", "_");

        // add name prefix if prefix exists
        if (namePrefix != null) {
            return namePrefix + "." + sanitizedName;
        }
        return sanitizedName;
    }

    /**
     * Valid characters are: alphanumeric, hyphen ("-"), underscore ("_"), dot (".")
     */
    @Override
    public String tagKey(String key) {
        return delegate.tagKey(key).replaceAll("[^a-zA-Z0-9\\-_\\.]", "_");
    }

    /**
     * We recommend enclosing tag values with double quotes (" "). If you surround the value with quotes any character is allowed,
     * including spaces. To include a double quote, escape it with a backslash. The backslash cannot
     * be the last character in the tag value.
     */
    @Override
    public String tagValue(String value) {
        String sanitized = delegate.tagValue(value);
        return StringEscapeUtils.escapeJson(sanitized.endsWith("\\") ?
                sanitized.substring(0, sanitized.length() - 1) + "_" :
                sanitized);
    }
}

@@ -642,16 +642,49 @@
 front;%0A%0A
+import java.util.regex.Pattern;%0A%0A
 import i
@@ -719,16 +719,16 @@
 .Meter;%0A
-
 import i
@@ -953,16 +953,223 @@
 ntion %7B%0A
+%0A    private static final Pattern PATTERN_NAME_TO_SANITIZE = Pattern.compile(%22%5B%5Ea-zA-Z0-9%5C%5C-_%5C%5C./,%5D%22);%0A    private static final Pattern PATTERN_TAG_KEY_TO_SANITIZE = Pattern.compile(%22%5B%5Ea-zA-Z0-9%5C%5C-_%5C%5C.%5D%22);%0A%0A
     priv
@@ -1916,23 +1916,23 @@
  String 
-sanitiz
+delegat
 edName =
@@ -1928,24 +1928,29 @@
 gatedName = 
+this.
 delegate.nam
@@ -1976,45 +1976,100 @@
 nit)
-.replaceAll(%22%5B%5Ea-zA-Z0-9%5C%5C-_%5C%5C./,%5D%22, 
+;%0A        String sanitizedName = PATTERN_NAME_TO_SANITIZE.matcher(delegatedName).replaceAll(
 %22_%22)
@@ -2415,70 +2415,139 @@
     
-return delegate.tagKey(key).replaceAll(%22%5B%5Ea-zA-Z0-9%5C%5C-_%5C%5C.%5D%22, 
+String delegatedTagKey = this.delegate.tagKey(key);%0A        return PATTERN_TAG_KEY_TO_SANITIZE.matcher(delegatedTagKey).replaceAll(
 %22_%22)

Use pre-compiled patterns in WavefrontNamingConvention