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

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import org.apache.logging.log4j.core.pattern.PatternParser;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
import org.apache.logging.log4j.core.util.Charsets;

@Plugin(
   name = "PatternLayout",
   category = "Core",
   elementType = "layout",
   printObject = true
)
public final class PatternLayout extends AbstractStringLayout {
   public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";
   public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %x - %m%n";
   public static final String SIMPLE_CONVERSION_PATTERN = "%d [%t] %p %c - %m%n";
   public static final String KEY = "Converter";
   private final List<PatternFormatter> formatters;
   private final String conversionPattern;
   private final Configuration config;
   private final RegexReplacement replace;
   private final boolean alwaysWriteExceptions;
   private final boolean noConsoleNoAnsi;

   private PatternLayout(Configuration config, RegexReplacement replace, String pattern, Charset charset, boolean alwaysWriteExceptions, boolean noConsoleNoAnsi, String header, String footer) {
      super(charset, toBytes(header, charset), toBytes(footer, charset));
      this.replace = replace;
      this.conversionPattern = pattern;
      this.config = config;
      this.alwaysWriteExceptions = alwaysWriteExceptions;
      this.noConsoleNoAnsi = noConsoleNoAnsi;
      PatternParser parser = createPatternParser(config);
      this.formatters = parser.parse(pattern == null ? "%m%n" : pattern, this.alwaysWriteExceptions, this.noConsoleNoAnsi);
   }

   private static byte[] toBytes(String str, Charset charset) {
      return str != null ? str.getBytes(charset != null ? charset : Charset.defaultCharset()) : null;
   }

   private byte[] strSubstitutorReplace(byte... b) {
      if (b != null && this.config != null) {
         Charset cs = this.getCharset();
         return this.config.getStrSubstitutor().replace(new String(b, cs)).getBytes(cs);
      } else {
         return b;
      }
   }

   public byte[] getHeader() {
      return this.strSubstitutorReplace(super.getHeader());
   }

   public byte[] getFooter() {
      return this.strSubstitutorReplace(super.getFooter());
   }

   public String getConversionPattern() {
      return this.conversionPattern;
   }

   public Map<String, String> getContentFormat() {
      Map<String, String> result = new HashMap();
      result.put("structured", "false");
      result.put("formatType", "conversion");
      result.put("format", this.conversionPattern);
      return result;
   }

   public String toSerializable(LogEvent event) {
      StringBuilder buf = new StringBuilder();
      Iterator i$ = this.formatters.iterator();

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

      String str = buf.toString();
      if (this.replace != null) {
         str = this.replace.format(str);
      }

      return str;
   }

   public static PatternParser createPatternParser(Configuration config) {
      if (config == null) {
         return new PatternParser(config, "Converter", LogEventPatternConverter.class);
      } else {
         PatternParser parser = (PatternParser)config.getComponent("Converter");
         if (parser == null) {
            parser = new PatternParser(config, "Converter", LogEventPatternConverter.class);
            config.addComponent("Converter", parser);
            parser = (PatternParser)config.getComponent("Converter");
         }

         return parser;
      }
   }

   public String toString() {
      return this.conversionPattern;
   }

   @PluginFactory
   public static PatternLayout createLayout(@PluginAttribute(value = "pattern",defaultString = "%m%n") String pattern, @PluginConfiguration Configuration config, @PluginElement("Replace") RegexReplacement replace, @PluginAttribute(value = "charset",defaultString = "UTF-8") Charset charset, @PluginAttribute(value = "alwaysWriteExceptions",defaultBoolean = true) boolean alwaysWriteExceptions, @PluginAttribute(value = "noConsoleNoAnsi",defaultBoolean = false) boolean noConsoleNoAnsi, @PluginAttribute("header") String header, @PluginAttribute("footer") String footer) {
      return newBuilder().withPattern(pattern).withConfiguration(config).withRegexReplacement(replace).withCharset(charset).withAlwaysWriteExceptions(alwaysWriteExceptions).withNoConsoleNoAnsi(noConsoleNoAnsi).withHeader(header).withFooter(footer).build();
   }

   public static PatternLayout createDefaultLayout() {
      return newBuilder().build();
   }

   @PluginBuilderFactory
   public static PatternLayout.Builder newBuilder() {
      return new PatternLayout.Builder();
   }

   // $FF: synthetic method
   PatternLayout(Configuration x0, RegexReplacement x1, String x2, Charset x3, boolean x4, boolean x5, String x6, String x7, Object x8) {
      this(x0, x1, x2, x3, x4, x5, x6, x7);
   }

   public static class Builder implements org.apache.logging.log4j.core.util.Builder<PatternLayout> {
      @PluginBuilderAttribute
      private String pattern;
      @PluginConfiguration
      private Configuration configuration;
      @PluginElement("Replace")
      private RegexReplacement regexReplacement;
      @PluginBuilderAttribute
      private Charset charset;
      @PluginBuilderAttribute
      private boolean alwaysWriteExceptions;
      @PluginBuilderAttribute
      private boolean noConsoleNoAnsi;
      @PluginBuilderAttribute
      private String header;
      @PluginBuilderAttribute
      private String footer;

      private Builder() {
         this.pattern = "%m%n";
         this.configuration = null;
         this.regexReplacement = null;
         this.charset = Charsets.UTF_8;
         this.alwaysWriteExceptions = true;
         this.noConsoleNoAnsi = false;
         this.header = null;
         this.footer = null;
      }

      public PatternLayout.Builder withPattern(String pattern) {
         this.pattern = pattern;
         return this;
      }

      public PatternLayout.Builder withConfiguration(Configuration configuration) {
         this.configuration = configuration;
         return this;
      }

      public PatternLayout.Builder withRegexReplacement(RegexReplacement regexReplacement) {
         this.regexReplacement = regexReplacement;
         return this;
      }

      public PatternLayout.Builder withCharset(Charset charset) {
         this.charset = charset;
         return this;
      }

      public PatternLayout.Builder withAlwaysWriteExceptions(boolean alwaysWriteExceptions) {
         this.alwaysWriteExceptions = alwaysWriteExceptions;
         return this;
      }

      public PatternLayout.Builder withNoConsoleNoAnsi(boolean noConsoleNoAnsi) {
         this.noConsoleNoAnsi = noConsoleNoAnsi;
         return this;
      }

      public PatternLayout.Builder withHeader(String header) {
         this.header = header;
         return this;
      }

      public PatternLayout.Builder withFooter(String footer) {
         this.footer = footer;
         return this;
      }

      public PatternLayout build() {
         if (this.configuration == null) {
            this.configuration = new DefaultConfiguration();
         }

         return new PatternLayout(this.configuration, this.regexReplacement, this.pattern, this.charset, this.alwaysWriteExceptions, this.noConsoleNoAnsi, this.header, this.footer);
      }

      // $FF: synthetic method
      Builder(Object x0) {
         this();
      }
   }
}
