// Path: src/main/java/com/performizeit/mjprof/parser/ThreadDump.java
// public class ThreadDump {
//   protected JStackHeader header;
//   ArrayList<ThreadInfo> stacks = new ArrayList<>();
//   int JNIglobalReferences = -1;
// 
//   public static String JNI_GLOBAL_REFS = "JNI global references:";
// 
//   public JStackHeader getHeader() {
//     return header;
//   }
// 
//   public ThreadDump(String stringRep) {
//     String[] splitTraces = stringRep.split("\n\"");  // Assuming that thread stack trace starts with a new line followed by "
// 
//     header = new JStackHeader(splitTraces[0]);
//     for (int i = 1; i < splitTraces.length; i++) {
//       if (splitTraces[i].startsWith(JNI_GLOBAL_REFS)) {
//         try {
//           JNIglobalReferences = Integer.parseInt(splitTraces[i].substring(splitTraces[i].indexOf(":") + 2).trim());
//         } catch (NumberFormatException e) {
//           // do nothing so we missed the JNI global references I do not know what to do with it.
//         }
// 
//       } else {
//         stacks.add(new ThreadInfo("\"" + splitTraces[i]));
//       }
//     }
//   }
// 
//   public ThreadDump() {
//     super();
//   }
// 
//   public ArrayList<ThreadInfo> getStacks() {
//     return stacks;
//   }
// 
//   public void addThreadInfo(ThreadInfo ti) {
//     stacks.add(ti);
//   }
// 
//   public void setStacks(ArrayList<ThreadInfo> stacks) {
//     this.stacks = stacks;
//   }
// 
//   @Override
//   public String toString() {
//     StringBuilder s = new StringBuilder();
//     s.append(header).append("\n\n");
// 
//     for (ThreadInfo stack : stacks) {
//       s.append(stack.toString()).append("\n");
//     }
// 
//     return s.toString();
//   }
// 
// 
//   public void setHeader(String header) {
//     this.header = new JStackHeader(header);
//   }
// 
//   public void setHeader(JStackHeader header) {
//     this.header = header;
//   }
// 
//   public ArrayList<ThreadInfo> cloneStacks() {
//     ArrayList<ThreadInfo> newStcks = new ArrayList<>();
//     for (ThreadInfo stk : getStacks()) {
//       newStcks.add(stk);
//     }
//     return newStcks;
//   }
// 
//   public int getJNIglobalReferences() {
//     return JNIglobalReferences;
//   }
// 
//   public void setJNIglobalReferences(int JNIglobalReferences) {
//     this.JNIglobalReferences = JNIglobalReferences;
//   }
// }
// 
// Path: src/main/java/com/performizeit/plumbing/GeneratorHandler.java
// public interface GeneratorHandler<E> {
//   E generate();
//   boolean isDone();
//   void sleepBetweenIteration();
// }


import com.performizeit.mjprof.plugin.types.DataSource;
import com.performizeit.mjprof.api.Plugin;
import com.performizeit.mjprof.api.Param;
import com.performizeit.mjprof.parser.ThreadDump;
import com.performizeit.plumbing.GeneratorHandler;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.AttachNotSupportedException;
import sun.jvmstat.monitor.*;
import sun.tools.attach.HotSpotVirtualMachine;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;
package com.performizeit.mjprof.plugins.dataSource;




@SuppressWarnings("unused")
@Plugin(name = "jstack", params = {@Param(type = String.class, value = "pid|mainClassName"),
  @Param(type = int.class, value = "count", optional = true, defaultValue = "1"),
  @Param(type = int.class, value = "sleep", optional = true, defaultValue = "5000")},
  description = "Generates dumps using jstack")
// Path: src/main/java/com/performizeit/mjprof/parser/ThreadDump.java
// public class ThreadDump {
//   protected JStackHeader header;
//   ArrayList<ThreadInfo> stacks = new ArrayList<>();
//   int JNIglobalReferences = -1;
// 
//   public static String JNI_GLOBAL_REFS = "JNI global references:";
// 
//   public JStackHeader getHeader() {
//     return header;
//   }
// 
//   public ThreadDump(String stringRep) {
//     String[] splitTraces = stringRep.split("\n\"");  // Assuming that thread stack trace starts with a new line followed by "
// 
//     header = new JStackHeader(splitTraces[0]);
//     for (int i = 1; i < splitTraces.length; i++) {
//       if (splitTraces[i].startsWith(JNI_GLOBAL_REFS)) {
//         try {
//           JNIglobalReferences = Integer.parseInt(splitTraces[i].substring(splitTraces[i].indexOf(":") + 2).trim());
//         } catch (NumberFormatException e) {
//           // do nothing so we missed the JNI global references I do not know what to do with it.
//         }
// 
//       } else {
//         stacks.add(new ThreadInfo("\"" + splitTraces[i]));
//       }
//     }
//   }
// 
//   public ThreadDump() {
//     super();
//   }
// 
//   public ArrayList<ThreadInfo> getStacks() {
//     return stacks;
//   }
// 
//   public void addThreadInfo(ThreadInfo ti) {
//     stacks.add(ti);
//   }
// 
//   public void setStacks(ArrayList<ThreadInfo> stacks) {
//     this.stacks = stacks;
//   }
// 
//   @Override
//   public String toString() {
//     StringBuilder s = new StringBuilder();
//     s.append(header).append("\n\n");
// 
//     for (ThreadInfo stack : stacks) {
//       s.append(stack.toString()).append("\n");
//     }
// 
//     return s.toString();
//   }
// 
// 
//   public void setHeader(String header) {
//     this.header = new JStackHeader(header);
//   }
// 
//   public void setHeader(JStackHeader header) {
//     this.header = header;
//   }
// 
//   public ArrayList<ThreadInfo> cloneStacks() {
//     ArrayList<ThreadInfo> newStcks = new ArrayList<>();
//     for (ThreadInfo stk : getStacks()) {
//       newStcks.add(stk);
//     }
//     return newStcks;
//   }
// 
//   public int getJNIglobalReferences() {
//     return JNIglobalReferences;
//   }
// 
//   public void setJNIglobalReferences(int JNIglobalReferences) {
//     this.JNIglobalReferences = JNIglobalReferences;
//   }
// }
// 
// Path: src/main/java/com/performizeit/plumbing/GeneratorHandler.java
// public interface GeneratorHandler<E> {
//   E generate();
//   boolean isDone();
//   void sleepBetweenIteration();
// }


// Path: src/main/java/com/performizeit/mjprof/plugins/dataSource/JstackDataSourcePlugin.java
import com.performizeit.mjprof.plugin.types.DataSource;
import com.performizeit.mjprof.api.Plugin;
import com.performizeit.mjprof.api.Param;
import com.performizeit.mjprof.parser.ThreadDump;
import com.performizeit.plumbing.GeneratorHandler;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.AttachNotSupportedException;
import sun.jvmstat.monitor.*;
import sun.tools.attach.HotSpotVirtualMachine;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;

package com.performizeit.mjprof.plugins.dataSource;




@SuppressWarnings("unused")
@Plugin(name = "jstack", params = {@Param(type = String.class, value = "pid|mainClassName"),
  @Param(type = int.class, value = "count", optional = true, defaultValue = "1"),
  @Param(type = int.class, value = "sleep", optional = true, defaultValue = "5000")},
  description = "Generates dumps using jstack")
public class JstackDataSourcePlugin implements DataSource, GeneratorHandler<ThreadDump> {