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;
import org.apache.logging.log4j.core.util.Patterns;

@Plugin(
   name = "style",
   category = "Converter"
)
@ConverterKeys({"style"})
public final class StyleConverter extends LogEventPatternConverter implements AnsiConverter {
   private final List<PatternFormatter> patternFormatters;
   private final boolean noAnsi;
   private final String style;
   private final String defaultStyle;

   public static StyleConverter newInstance(Configuration config, String[] options) {
      if (options.length < 1) {
         LOGGER.error("Incorrect number of options on style. Expected at least 1, received " + options.length);
         return null;
      } else if (options[0] == null) {
         LOGGER.error("No pattern supplied on style");
         return null;
      } else if (options[1] == null) {
         LOGGER.error("No style attributes provided");
         return null;
      } else {
         PatternParser parser = PatternLayout.createPatternParser(config);
         List<PatternFormatter> formatters = parser.parse(options[0]);
         String style = AnsiEscape.createSequence(options[1].split(Patterns.COMMA_SEPARATOR));
         boolean noConsoleNoAnsi = options.length > 2 && "noConsoleNoAnsi=true".equals(options[2]);
         boolean hideAnsi = noConsoleNoAnsi && System.console() == null;
         return new StyleConverter(formatters, style, hideAnsi);
      }
   }

   private StyleConverter(List<PatternFormatter> patternFormatters, String style, boolean noAnsi) {
      super("style", "style");
      this.patternFormatters = patternFormatters;
      this.style = style;
      this.defaultStyle = AnsiEscape.getDefaultStyle();
      this.noAnsi = noAnsi;
   }

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

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

      if (buf.length() > 0) {
         if (this.noAnsi) {
            toAppendTo.append(buf.toString());
         } else {
            toAppendTo.append(this.style).append(buf.toString()).append(this.defaultStyle);
         }
      }

   }

   public boolean handlesThrowable() {
      Iterator i$ = this.patternFormatters.iterator();

      PatternFormatter formatter;
      do {
         if (!i$.hasNext()) {
            return false;
         }

         formatter = (PatternFormatter)i$.next();
      } while(!formatter.handlesThrowable());

      return true;
   }

   public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append(super.toString());
      sb.append("[style=");
      sb.append(this.style);
      sb.append(", defaultStyle=");
      sb.append(this.defaultStyle);
      sb.append(", patternFormatters=");
      sb.append(this.patternFormatters);
      sb.append(", noAnsi=");
      sb.append(this.noAnsi);
      sb.append(']');
      return sb.toString();
   }
}
