package pta;

import java.util.Collection;

import driver.PTAOptions;
import pag.node.GNode;
import pag.node.alloc.SummaryNode;
import pag.node.call.VirtualInvokeSite;
import pag.node.var.AllocDotField_Node;
import pag.node.var.Var_Node;
import soot.SootClass;
import soot.SootMethod;
import soot.Type;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.Stmt;
import soot.util.queue.QueueReader;

public interface SubPTAInterface{
	
	static SubPTAInterface createSubPTA(SootMethod entryMethod) {
		return PTAOptions.subptaPattern.isInsensitive()?new SubPTA(entryMethod):
				new SubContextSensPTA(entryMethod,
						PTAOptions.subptaPattern.getContextDepth(), 
						PTAOptions.subptaPattern.getHeapContextDepth(),
						PTAOptions.subptaPattern.getContextKind());
	};
	
	static boolean isPoly(VirtualInvokeSite site){
        if(!PTAOptions.checkSignature)
            return true;
        InstanceInvokeExpr iie = site.iie();
        SootMethod method = iie.getMethod();
        if(method.isFinal()||method.isPrivate())
            return false;
        SootClass sootClass = method.getDeclaringClass();
        return !sootClass.isFinal();
    }
	
	boolean isIgnore();
	
	public void setIgnore();

	SootMethod getEntryMethod();
	
	/**Implementation of Algorithm 2*/
	Collection<Stmt> makeSummary();

	/**Implementation of get*Node*/
	SummaryNode getSummaryNode(Object n, Type type);

	default SummaryNode getSummaryNode(GNode n) {
		return getSummaryNode(n, n.getType());
	}
	boolean isFullSummaryNode(GNode n);
	
	/** record modified summary nodes which is to be handled in Algorithm 2(Lines 9-14).*/
	void recordModified(AllocDotField_Node oDotF);

	QueueReader<Var_Node> unprocessedArgQueueReader();

	boolean isUnprocessedArg(Var_Node src);
}
