package Detectors;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

import Smells.BadFiledName;
import Smells.BadParameterName;
import Smells.SMELLTYPE;
import Smells.Smell;
import Smells.SwitchStatements;

public class VisitorOfAST extends ASTVisitor {
	private List<List<SwitchStatement>> allMatchedSwitchLists = new ArrayList<List<SwitchStatement>>();
	private List<SwitchStatement> NotMatchswitches = new ArrayList<SwitchStatement>();
 
	private List<VariableDeclarationFragment>BadNameList=new ArrayList<VariableDeclarationFragment>();
	private List<SingleVariableDeclaration>BadNameList2=new ArrayList<SingleVariableDeclaration>();
	
	// private List<List<SwitchStatement>> getMatchedSwitches(){return allMatchedSwitchLists;}
	
	 
	public VisitorOfAST() {
		// TODO Auto-generated constructor stub

	}

	public VisitorOfAST(boolean visitDocTags) { 
		super(visitDocTags);
		// TODO Auto-generated constructor stub
	}

	
	public boolean visit(VariableDeclarationFragment node) 
	{//System.out.println("Fragment*******"+node);
	      
	       //System.out.println("node.getName"+node.getName());
	       String Name=node.getName().toString();
	       if(Name.length()==1)
	       {
	    	   BadNameList.add(node);
	    	   
	    
	       }
	       
	       return true;
	
	
	
	         }//局部全局都可以实现
	
	public List<Smell> getBadName(IResource resource, CompilationUnit unit)
	{
	  List<Smell> smellList=new ArrayList<Smell>();
	  for (VariableDeclarationFragment aList:BadNameList)
	  {
		  
		    Smell asmell=new BadFiledName();
		
			asmell.resource = resource;
			asmell.unit = unit;
			asmell.associatedNode=aList;
			asmell.setStartPoint(aList.getStartPosition());
			asmell.setLength(1);
			asmell.explaination="The name "+" ' "+aList.getName().toString().trim()+" ' "+" is a bad name.";
			smellList.add(asmell);
		   
			
			
			
		    
	  }
	  return smellList;
		
	}
	
	
	
	public boolean visit(SingleVariableDeclaration node) 
	{//System.out.println("Expression*******"+node);
	       
	        String Name=node.getName().toString();
		       if(Name.length()==1)
		       {
		    	   BadNameList2.add(node);
		    	   
		    
		       }
		       
	       
	       return true;
	
	
	
	         }
	
	public List<Smell> getBadName2(IResource resource, CompilationUnit unit)
	{
	  List<Smell> smellList=new ArrayList<Smell>();
	  for (SingleVariableDeclaration aList:BadNameList2)
	  {
		  
		    Smell asmell=new BadParameterName();
		
			asmell.resource = resource;
			asmell.unit = unit;
			asmell.associatedNode=aList;
			asmell.setStartPoint(aList.getName().getStartPosition());
			asmell.setLength(1);
			asmell.explaination="The name "+" ' "+aList.getName().toString()+" ' "+" is a bad name.";
			smellList.add(asmell);
		   		
		    
	  }
	  return smellList;
		
	}
	
	
	
	
	

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	 
	@Override
	public boolean visit(SwitchStatement node) {

		for (List<SwitchStatement> aSwitchList : allMatchedSwitchLists) {
			if (compSwitch(node, aSwitchList)) {
				// matched, add to the currrent match list
				aSwitchList.add(node);
				return true;
			}
		}

      return	compNotMatchSwitch(node, NotMatchswitches);
		// 具体匹配对的创建、旧match的删除等全部在这个函数内完成了。

		
	}
public List<Smell> getSwitchSmells(IResource resource, CompilationUnit unit)
{
  List<Smell> smellList=new ArrayList<Smell>();
  for (List<SwitchStatement> aList:allMatchedSwitchLists)
  {
	    SwitchStatement statement=aList.get(0);
	    Smell asmell=new SwitchStatements();
	
		asmell.resource = resource;
		asmell.unit = unit;
		asmell.setStartPoint(statement.getStartPosition());
		////System.out.print("**Switch 的表达式是"+statement.getExpression().toString());
		//asmell.StartPoint(statement.getStartPosition());
		asmell.setLength(statement.getLength());
	    asmell.SwitchState =statement.getExpression().toString();
		

		
		
		////System.out.print("asmell.switchstring="+asmell.switchstring);
		
		asmell.explaination="Similar structured switch statements should be removed by polimphish";
		smellList.add(asmell);
		
	    
  }
  return smellList;
	
}
	private boolean compSwitch(SwitchStatement node,
			List<SwitchStatement> aSwitchList) {
		String express = node.getExpression().toString().trim();
		if (aSwitchList.size() < 1)
			return false;
	

		// compare with the first switch stored in the List
		SwitchStatement oldSwitch = aSwitchList.get(0);
		String oldExpress = oldSwitch.getExpression().toString().trim();
		if (express.compareToIgnoreCase(oldExpress) != 0) {
			return false;
		}
		// compare each CASE statemetn
		List<Statement> cases = node.statements();
		List<Statement> cases2 = oldSwitch.statements();

		for (Statement newCase : cases) {
			 if(!(newCase instanceof SwitchCase)) continue;
			boolean caseMatched = false;
			for (Statement oldCase : cases2) {
				 if(!(oldCase instanceof SwitchCase)) continue;
				if (((SwitchCase)newCase).getExpression().toString().trim().compareToIgnoreCase(
						((SwitchCase)oldCase).getExpression().toString().trim()) == 0) {
					
				  
					 
					
					caseMatched = true;
					break;// find a match
				}
			}
			if (caseMatched == false) {// 一旦一个casematch不上，就是无匹配
				return false;

			}

		}
		
		 
		return true;

	}

	private boolean compNotMatchSwitch(SwitchStatement node,
			List<SwitchStatement> aSwitchList) {
		String express = node.getExpression().toString().trim();
	
		for (SwitchStatement oldSwitch : aSwitchList) {// compare with each
			// switch stored in the
			// List
			String oldExpress = oldSwitch.getExpression().toString().trim();
			if (express.compareToIgnoreCase(oldExpress) != 0) {
				continue;
			}
			// compare each CASE statement
			List<Statement> Newstatements=node.statements();
			List<Statement> newStatements = oldSwitch.statements();
			boolean isMatched = true;
			for (Statement newCase : Newstatements) {
                   if(!(newCase instanceof SwitchCase)) continue;
				boolean caseMatched = false;
				for (Statement oldCase : newStatements) {
			           if(!(oldCase instanceof SwitchCase)) continue;
					 int result=((SwitchCase)newCase).getExpression().toString().trim().compareToIgnoreCase(
							 ((SwitchCase)oldCase).getExpression().toString().trim());
						if (result == 0) {
						caseMatched = true;
						break;// find a match
					}
				}
				isMatched = isMatched & caseMatched;
				if (caseMatched == false) {
					break;
				}// 这个swithc肯定无法匹配，不在禅师后续的case条件语句}
			}
          if(isMatched==true)
          {
        	  //find the matched.
        	  List<SwitchStatement>newMatchedswitches = new ArrayList<SwitchStatement>();
        	  newMatchedswitches.add(node);
        	  newMatchedswitches.add(oldSwitch);
        	  allMatchedSwitchLists.add(newMatchedswitches);
      		  aSwitchList.remove(oldSwitch);    	   		
      		 return true; //不需要继续比较其他switch语句了
      		        	  
          }
		}
		//没有找到任何匹配的
		aSwitchList.add(node);
		return false;

	}

}
