package com.eactive.eai.adapter.socket2.protocol.http.servlet;

import java.util.Arrays;
import java.util.Hashtable;


public class ThreadDumpUtil {
    @SuppressWarnings("deprecation")
	public static void kill(String threadName) {     
        ThreadGroup it = Thread.currentThread().getThreadGroup();
        Thread[] threads = new Thread[it.activeCount()] ;
        it.enumerate(threads);
    	for (int i=0; i<threads.length; i++) {        
    		if (threads[i].getName().equals(threadName)) {
    			threads[i].interrupt();
    			threads[i].stop();
//    			System.out.println("kill thread - " + threadName);
    			return;
    		}
    	}
    }
    public static String dump(String filter) {
    	Hashtable hash = new Hashtable();
    	StringBuilder sb = new StringBuilder();        
        ThreadGroup it = Thread.currentThread().getThreadGroup();

        //sb.append("[group] " + it.getName() + "<p><p><p>");

        Thread[] threads = new Thread[it.activeCount()] ;
        //sb.append("thread count : " + it.activeCount() + "<p>");
        it.enumerate(threads);
        sb.append("<table border='0' align='left'>");
        
    	String[] threadNames = new String[threads.length];
    	for (int i=0; i<threadNames.length; i++) {
    		threadNames[i] = threads[i].getName() + " - " + threads[i].getState();
    		hash.put(threadNames[i], threads[i]);
    	}
    	Arrays.sort(threadNames);
        
    	int filterThreadCount = 0;
        for(int i=0;i<threadNames.length;i++) {    	
        	if (threadNames[i].toUpperCase().indexOf(filter.toUpperCase()) == -1) {
        		continue;
        	}
        	
        	Thread thread = (Thread) hash.get(threadNames[i]);
            if(thread != null) {
                sb.append("<tr>");
                //sb.append(getStackTrace(threads[i]));
                sb.append(getStackTrace(thread));
                sb.append("</tr>");
            }
            filterThreadCount++;
        }
        sb.append("</table>");
        
        StringBuilder sbb = new StringBuilder();
        sbb.append("thread count : " + filterThreadCount + " / " + it.activeCount() + "<p><br>");
        sbb.append(sb);
    	return sbb.toString();
    }
    
    static public String getStackTrace(Thread thread) {
    	StringBuilder sb = new StringBuilder();
        sb.append("■ \"<b>" + thread.getName() + "</b>\" ");
        sb.append("prio=" + thread.getPriority() + " ");
        sb.append(thread.isDaemon() ? "daemon " : " ");
        
        StackTraceElement stack[] = thread.getStackTrace();

        if (stack==null || stack.length<1)
	        return sb.toString();

        if (stack[0].getMethodName().equals("wait"))
            sb.append("<b>wait</b> ");
        else if (stack[0].getMethodName().equals("sleep"))
            sb.append("<b>sleep</b> ");
        else
            sb.append("<b><font color='red'>running or blocked</font></b> ");
        
        //sb.append("  (<a href='/thread?kill=" + thread.getName() + "'>kill</a>)");
        sb.append("\n");

        for (int i=0; i<stack.length; i++) {
            String filename = stack[i].getFileName();
            if (filename == null) {
                // The source filename is not available
            }
            String className = stack[i].getClassName();
            String methodName = stack[i].getMethodName();
            boolean isNativeMethod = stack[i].isNativeMethod();
            int line = stack[i].getLineNumber();

            if (className.startsWith("java") 
            	|| className.startsWith("org.") 
            	|| className.startsWith("sun.") 
            	|| className.startsWith("com.sun.") 
            	|| className.startsWith("edu.emory."))
                sb.append("      <font color='gray'>at ");
            else
                sb.append("      at ");
            sb.append(className + "." + methodName);
            sb.append("(" + filename + ":" + (isNativeMethod ? "native" : String.valueOf(line)) + ")");
            if (className.startsWith("java") 
            	|| className.startsWith("org.") 
            	|| className.startsWith("sun.") 
            	|| className.startsWith("com.sun.") 
            	|| className.startsWith("edu.emory."))
                sb.append("</font>");
            sb.append("\n");
        }
        
        if (stack[0].getMethodName().equals("wait"))
            return "<td><pre>" + sb.toString() + "</pre></td>";
        else if (stack[0].getMethodName().equals("sleep"))
            return "<td bgcolor=''><pre>" + sb.toString() + "</pre></td>";
        else
            return "<td bgcolor=''><pre>" + sb.toString() + "</pre></td>";
    }
    
    
//    static public String dump() {
//    	StringBuffer sb = new StringBuffer();
//    	ThreadGroup it = Thread.currentThread().getThreadGroup();
//    	sb.append("[group] " + it.getName() + "\n");
//    	Thread[] threads = new Thread[it.activeCount()] ;
//    	sb.append("active count : "+it.activeCount() + "\n");
//    	it.enumerate(threads);
//    	
//    	//----------------------------------------------------------------------
//    	///*
//    	String[] threadNames = new String[threads.length];
//    	for (int i=0; i<threadNames.length; i++) {
//    		threadNames[i] = threads[i].getName() + " - " + threads[i].getState();
//    	}
//    	Arrays.sort(threadNames);
//    	for (int i=0; i<threadNames.length; i++) {
//    		sb.append("[" + i + "] " + threadNames[i] + "\n");
//    	}
//    	//*/
//    	
//    	//----------------------------------------------------------------------
//        for(int i=0;i<threads.length;i++) {
//        	if(threads[i]!=null) {
//        		sb.append(getStackTrace(threads[i]));
//        		//sb.append(threads[i].getName() + "\n");
//        	}
//        }
//
//        return sb.toString();
//    }
}
