package org.apache.logging.log4j.message;

import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class ThreadDumpMessage implements Message {
   private static final long serialVersionUID = -1103400781608841088L;
   private static final ThreadDumpMessage.ThreadInfoFactory FACTORY;
   private volatile Map<ThreadInformation, StackTraceElement[]> threads;
   private final String title;
   private String formattedMessage;

   public ThreadDumpMessage(String title) {
      this.title = title == null ? "" : title;
      this.threads = FACTORY.createThreadInfo();
   }

   private ThreadDumpMessage(String formattedMsg, String title) {
      this.formattedMessage = formattedMsg;
      this.title = title == null ? "" : title;
   }

   public String toString() {
      StringBuilder sb = new StringBuilder("ThreadDumpMessage[");
      if (this.title.length() > 0) {
         sb.append("Title=\"").append(this.title).append('"');
      }

      sb.append(']');
      return sb.toString();
   }

   public String getFormattedMessage() {
      if (this.formattedMessage != null) {
         return this.formattedMessage;
      } else {
         StringBuilder sb = new StringBuilder(this.title);
         if (this.title.length() > 0) {
            sb.append('\n');
         }

         Iterator i$ = this.threads.entrySet().iterator();

         while(i$.hasNext()) {
            Entry<ThreadInformation, StackTraceElement[]> entry = (Entry)i$.next();
            ThreadInformation info = (ThreadInformation)entry.getKey();
            info.printThreadInfo(sb);
            info.printStack(sb, (StackTraceElement[])entry.getValue());
            sb.append('\n');
         }

         return sb.toString();
      }
   }

   public String getFormat() {
      return this.title == null ? "" : this.title;
   }

   public Object[] getParameters() {
      return null;
   }

   protected Object writeReplace() {
      return new ThreadDumpMessage.ThreadDumpMessageProxy(this);
   }

   private void readObject(ObjectInputStream stream) throws InvalidObjectException {
      throw new InvalidObjectException("Proxy required");
   }

   public Throwable getThrowable() {
      return null;
   }

   // $FF: synthetic method
   ThreadDumpMessage(String x0, String x1, Object x2) {
      this(x0, x1);
   }

   static {
      Method[] methods = ThreadInfo.class.getMethods();
      boolean basic = true;
      Method[] arr$ = methods;
      int len$ = methods.length;

      for(int i$ = 0; i$ < len$; ++i$) {
         Method method = arr$[i$];
         if (method.getName().equals("getLockInfo")) {
            basic = false;
            break;
         }
      }

      FACTORY = (ThreadDumpMessage.ThreadInfoFactory)(basic ? new ThreadDumpMessage.BasicThreadInfoFactory() : new ThreadDumpMessage.ExtendedThreadInfoFactory());
   }

   private static class ExtendedThreadInfoFactory implements ThreadDumpMessage.ThreadInfoFactory {
      private ExtendedThreadInfoFactory() {
      }

      public Map<ThreadInformation, StackTraceElement[]> createThreadInfo() {
         ThreadMXBean bean = ManagementFactory.getThreadMXBean();
         ThreadInfo[] array = bean.dumpAllThreads(true, true);
         Map<ThreadInformation, StackTraceElement[]> threads = new HashMap(array.length);
         ThreadInfo[] arr$ = array;
         int len$ = array.length;

         for(int i$ = 0; i$ < len$; ++i$) {
            ThreadInfo info = arr$[i$];
            threads.put(new ExtendedThreadInformation(info), info.getStackTrace());
         }

         return threads;
      }

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

   private static class BasicThreadInfoFactory implements ThreadDumpMessage.ThreadInfoFactory {
      private BasicThreadInfoFactory() {
      }

      public Map<ThreadInformation, StackTraceElement[]> createThreadInfo() {
         Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
         Map<ThreadInformation, StackTraceElement[]> threads = new HashMap(map.size());
         Iterator i$ = map.entrySet().iterator();

         while(i$.hasNext()) {
            Entry<Thread, StackTraceElement[]> entry = (Entry)i$.next();
            threads.put(new BasicThreadInformation((Thread)entry.getKey()), entry.getValue());
         }

         return threads;
      }

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

   private interface ThreadInfoFactory {
      Map<ThreadInformation, StackTraceElement[]> createThreadInfo();
   }

   private static class ThreadDumpMessageProxy implements Serializable {
      private static final long serialVersionUID = -3476620450287648269L;
      private final String formattedMsg;
      private final String title;

      public ThreadDumpMessageProxy(ThreadDumpMessage msg) {
         this.formattedMsg = msg.getFormattedMessage();
         this.title = msg.title;
      }

      protected Object readResolve() {
         return new ThreadDumpMessage(this.formattedMsg, this.title);
      }
   }
}
