package com.wavefront.ingester;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;

/**
 * Given a raw graphite line, look for any host tag, and add it if implicit. Does not perform full
 * decoding, though.
 */
public class GraphiteHostAnnotator extends MessageToMessageDecoder<String> {

  private final Pattern sourceExistencePattern;
  private final String hostName;

  public GraphiteHostAnnotator(String hostName, List<String> customSourceTags) {
    this.hostName = hostName;
    StringBuffer pattern = new StringBuffer(".+(");
    for (String tag : customSourceTags) {
      pattern.append(tag);
      pattern.append("|");
    }
    pattern.append("source|host)=[^\\s].+");
    sourceExistencePattern = Pattern.compile(pattern.toString(), Pattern.CASE_INSENSITIVE);
  }

  // Decode from a possibly host-annotated graphite string to a definitely host-annotated graphite string.
  @Override
  protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
    Matcher m = sourceExistencePattern.matcher(msg);
    if (m.matches()) {
      // Has a source; add without change
      out.add(msg);
    } else {
      out.add(msg + " source=" + hostName);
    }
  }
}

@@ -43,16 +43,21 @@
 va.util.
+Array
 List;%0Aim
@@ -75,21 +75,12 @@
 til.
-regex.Matcher
+List
 ;%0Aim
@@ -98,21 +98,25 @@
 til.
-regex.Pattern
+stream.Collectors
 ;%0A%0Ai
@@ -443,38 +443,23 @@
 nal 
-Pattern sourceExistencePattern
+String hostName
 ;%0A  
@@ -472,31 +472,59 @@
 e final 
+List%3C
 String
- hostName
+%3E sourceTags = new ArrayList%3C%3E()
 ;%0A%0A  pub
@@ -565,16 +565,22 @@
 ostName,
+ final
  List%3CSt
@@ -643,672 +643,762 @@
     
-StringBuffer pattern = new StringBuffer(%22.+(%22);%0A    for (String tag : customSourceTags) %7B%0A      pattern.append(tag);%0A      pattern.append(%22%7C%22);%0A    %7D%0A    pattern.append(%22source%7Chost)=%5B%5E%5C%5Cs%5D.+%22);%0A    sourceExistencePattern = Pattern.compile(pattern.toString(), Pattern.CASE_INSENSITIVE);%0A  %7D%0A%0A  // Decode from a possibly host-annotated graphite string to a definitely host-annotated graphite string.%0A  @Override%0A  protected void decode(ChannelHandlerContext ctx, String msg, List%3CObject%3E out) throws Exception %7B%0A    Matcher m = sourceExistencePattern.matcher(msg);%0A    if (m.matches()) %7B%0A      // Has a source; add without change%0A      out.add(msg);%0A    %7D else %7B%0A  
+this.sourceTags.add(%22source=%22);%0A    this.sourceTags.add(%22host=%22);%0A    this.sourceTags.addAll(customSourceTags.stream().map(customTag -%3E customTag + %22=%22).collect(Collectors.toList()));%0A  %7D%0A%0A  // Decode from a possibly host-annotated graphite string to a definitely host-annotated graphite string.%0A  @Override%0A  protected void decode(ChannelHandlerContext ctx, String msg, List%3CObject%3E out) throws Exception %7B%0A    for (String tag : sourceTags) %7B%0A      int strIndex = msg.indexOf(tag);%0A      // if a source tags is found and is followed by a non-whitespace tag value, add without change%0A      if (strIndex %3E -1 && msg.length() - strIndex - tag.length() %3E 0 && msg.charAt(strIndex + tag.length()) %3E ' ') %7B%0A        out.add(msg);%0A        return;%0A      %7D%0A    %7D%0A
     
@@ -1435,20 +1435,14 @@
 tName);%0A
-    %7D%0A
   %7D%0A%7D%0A

Improve GraphiteHostAnnotator performance (#114)