package org.apache.logging.log4j.core.pattern;

import java.util.Iterator;
import java.util.List;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.layout.PatternLayout;

@Plugin(
   name = "encode",
   category = "Converter"
)
@ConverterKeys({"enc", "encode"})
public final class EncodingPatternConverter extends LogEventPatternConverter {
   private final List<PatternFormatter> formatters;

   private EncodingPatternConverter(List<PatternFormatter> formatters) {
      super("encode", "encode");
      this.formatters = formatters;
   }

   public static EncodingPatternConverter newInstance(Configuration config, String[] options) {
      if (options.length != 1) {
         LOGGER.error("Incorrect number of options on escape. Expected 1, received " + options.length);
         return null;
      } else if (options[0] == null) {
         LOGGER.error("No pattern supplied on escape");
         return null;
      } else {
         PatternParser parser = PatternLayout.createPatternParser(config);
         List<PatternFormatter> formatters = parser.parse(options[0]);
         return new EncodingPatternConverter(formatters);
      }
   }

   public void format(LogEvent event, StringBuilder toAppendTo) {
      StringBuilder buf = new StringBuilder();
      Iterator i$ = this.formatters.iterator();

      while(i$.hasNext()) {
         PatternFormatter formatter = (PatternFormatter)i$.next();
         formatter.format(event, buf);
      }

      for(int i = 0; i < buf.length(); ++i) {
         char c = buf.charAt(i);
         switch(c) {
         case '\n':
            toAppendTo.append("\\n");
            break;
         case '\r':
            toAppendTo.append("\\r");
            break;
         case '"':
            toAppendTo.append("&quot;");
            break;
         case '&':
            toAppendTo.append("&amp;");
            break;
         case '\'':
            toAppendTo.append("&apos;");
            break;
         case '/':
            toAppendTo.append("&#x2F;");
            break;
         case '<':
            toAppendTo.append("&lt;");
            break;
         case '>':
            toAppendTo.append("&gt;");
            break;
         default:
            toAppendTo.append(c);
         }
      }

   }
}
