package pta;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import driver.Config;
import driver.FakeMainFactory;
import pag.MethodPAG;
import soot.SootClass;
import soot.SootMethod;
import soot.jimple.Stmt;
import util.Debug;

/**Summary based PTA. will use summaries*/
public class SumPTA extends PTA{
	public static List<SootMethod> scalableMethods = new ArrayList<>();
	static Map<SootMethod, Collection<Stmt>> methodToSumStmts = new HashMap<>();
	public static long sumtime;
	public static Collection<Stmt> getMethodStmts(SootMethod m){
		Collection<Stmt> ret = methodToSumStmts.get(m);
		if (ret == null) {
			SubPTAInterface subpta = SubPTAInterface.createSubPTA(m);
			Debug.println(subpta);
			((PTA) subpta).purerun();
			methodToSumStmts.put(m, ret = subpta.makeSummary());
		}
		return ret;
	}
	
	@Override
	public MethodPAG getMethodPAG(SootMethod m){
		MethodPAG ret = methodToPag.get(m);
		if (ret == null) {
			Collection<Stmt> stmts;
			if(isLib(m)) {
				long start = System.currentTimeMillis();
				stmts = getMethodStmts(m);
				sumtime+=System.currentTimeMillis()-start;
			}else 
				stmts = PTA.getMethodStmts(m);
			methodToPag.put(m, ret = new MethodPAG(pag, m, stmts));
		}
		return ret;
	}

	public static boolean isLib(SootMethod m) {
		SootClass dclass = m.getDeclaringClass();
		if(dclass.getName().contains("_Lib"))// for testing
			return true;
		if(FakeMainFactory.v!=null&&m==FakeMainFactory.getFakeMain())
			return false;
		return !Config.v().isAppClass(m.getDeclaringClass());
	}
}
