import java.util.Iterator;
import java.util.List;
import soot.*;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.tagkit.Tag;
public class SootTest {
		public static void main(String args[]) {
				String strClass = "HelloWorld";
				//strClass is used here and also as the last param in the opts array
				SootClass sootClass = Scene.v().loadClassAndSupport(strClass);
				//just seeing what some of the functions do... looks like its reading in the file correctly
				System.out.println("Number of methods in " + sootClass.getName() + ": " + sootClass.getMethodCount());
				// String[] opts = {"-W", "-app", "-f", "jimple", "-p", "jb", "use-original-names:true", "-p", "cg.spark", "on", "-p", "cg.spark",
				//				"simplify-offline:true","-p", "cg.spark","on-fly-cg:true", "-p", "tag.ln","enabled:true",
                               //"-keep-line-number", strClass};
				 String [] opts = {"-W", "-keep-line-number", strClass };
				// String[] opts = {"-w", strClass};
				//have to set the application class
				System.out.println("Set Application classes");
				sootClass.setApplicationClass();
				Scene.v().setMainClass(sootClass);
				//set the options to the static main class
				System.out.println("Set options to the static main class");
				Main.main(opts);
				System.out.println("Get the call graph");
				//get the call graph
				CallGraph cg = Scene.v().getCallGraph();
				if(cg==null){
						System.out.println("Call graph is equal to null, exiting!");
				}else{
						System.out.println("Call graph is non null, analyzing");
						analyze(cg);
				}
		}
	public static void analyze(CallGraph cg){
			 int i = 0;
			 //print out what we've got.
			 for(Iterator iter = cg.sourceMethods(); iter.hasNext();){
					 SootMethod sootMethod = (SootMethod)iter.next();
					 System.out.println(i + " " + sootMethod.getName());
					 if(sootMethod.hasActiveBody()){
							 Body body = sootMethod.getActiveBody();
							 System.out.println("\t Active Body: "+body);
					 }else{
							 System.out.println("\t No Active Body Found!");
					 }
					 System.out.println("\t Byte Code Signature: "+sootMethod.getBytecodeSignature());
					 System.out.println("\t Declaration: "+sootMethod.getDeclaration());
					 System.out.println("\t Declaring Class: "+sootMethod.getDeclaringClass());
					 System.out.println("\t Modifiers: "+sootMethod.getModifiers());
					 System.out.println("\t Parameter Count: "+sootMethod.getParameterCount());
					 System.out.println("\t Return Type: "+sootMethod.getReturnType());
					 System.out.println("\t Signature: "+sootMethod.getSignature());
					 System.out.println("\t Sourhce: "+sootMethod.getSource());
					 List listTags = sootMethod.getTags();
					 if(listTags!=null){
							 for(int j=0; j<listTags.size(); j++){
									 Tag tag = (Tag) listTags.get(i);
									 System.out.println("\t\tTag " +j+" " +tag.getName());
							 }
					 }
					   i++;
				}
		}
}