package Smells;

import java.io.BufferedWriter;
import java.util.List;

import org.eclipse.jdt.core.dom.MethodDeclaration;
import Analysis.printer;
import Detectors.THRESHOLDS;

public class LongParameter extends Smell {
	public static int totalNoOfDetectorSmells=0;
	public static int totalNoOfDisparedSmells=0;
	public LongParameter() {
		setType(SMELLTYPE.LONGPARAMETER);
	}
  String Suggestion="Encapsulate small parameters as a big one (Menu  Refactor-->Introduce Parameter Object) ";
  public String getSuggestion()
	{
		return Suggestion;
		
		
	}
  
  
  
  public  static void AdjustThresholdAfterStatistics()
	{
		double RATION;
		if(totalNoOfDetectorSmells<=10)return;
		
	 RATION=totalNoOfDisparedSmells/totalNoOfDetectorSmells;
		if(! THRESHOLDS.IsOurOfRange( RATION))
		{ THRESHOLDS.setLONGPARAMETER(THRESHOLDS.AdjustThreshold(THRESHOLDS.getLONGPARAMETER(),  RATION));}
		totalNoOfDetectorSmells=0;
		totalNoOfDisparedSmells=0;
	}
	@Override
	public boolean Smellequal(Smell obj) {
	   	if(!(obj instanceof Smell)) return false;
	      Smell target= (Smell) obj;
	     if(target==null) return false;
	    // if(target.unit!=this.unit) return false;
	     if(target.getType()!=this.getType()) return false;
	   
	    	MethodDeclaration targetMethod= (MethodDeclaration)target.associatedNode;
	    	MethodDeclaration thisMethod=(MethodDeclaration)associatedNode;
	    	
	    	String targetTypeName=targetMethod.getName().getFullyQualifiedName().trim();
	       	String thisTypeName=thisMethod.getName().getFullyQualifiedName().trim();
	    	if(targetTypeName.compareToIgnoreCase(thisTypeName)!=0)
	    		return false;
	    	return true;	 
	}
	
	
	
	
	
	public void save(BufferedWriter bw)
	{   
	  
		
		String filelocation=this.resource.getLocation().toString();
		
		
		
		try{ 
			 bw.newLine();
			 bw.append(SMELLTYPE.getText(this.getType()));
			 bw.append(THRESHOLDS.tab);
			 bw.append(filelocation);
			 bw.append(THRESHOLDS.tab);
			 bw.append(Long.toString(this.appearTime));
			 bw.append(THRESHOLDS.tab);
	     if (!(this.associatedNode instanceof MethodDeclaration))  // obj是否是TypeDeclaration的一个实例
				return;// failed
	     MethodDeclaration Method = (MethodDeclaration) this.associatedNode;
			bw.append(Method.getName().toString());
			// bw.append(THRESHOLDS.tab);
		
			}
			catch(Exception e) {
  	     printer.print(e); }
		
		
	}
	public void forcomparation()
	{
		  if (!(this.associatedNode instanceof MethodDeclaration))  // obj是否是TypeDeclaration的一个实例
				return;// failed
	     MethodDeclaration Method = (MethodDeclaration) this.associatedNode;
			forcompareted=Method.getName().toString();
		}
		

	private static int totalSmellsWithCurrentThreshold=0;
	private static int totalRemovedSemllsWithCurrentThreshold=0;
	@Override
	public void toBeRmoved() {
		if(this.DetectedWithCurrentThreshold)
		{
			totalRemovedSemllsWithCurrentThreshold++;			
		}
	}

	@Override
	public void CountNewSmell() {
		if(this.DetectedWithCurrentThreshold)
		{
		    totalSmellsWithCurrentThreshold++;	
		}
	}
	public static boolean adjustThreshold(List<Smell> existing)
	{
	 printer.println("Total Semlls: " +totalSmellsWithCurrentThreshold);	
	 printer.println("Resovled Semlls: " +totalRemovedSemllsWithCurrentThreshold);
	 if(totalSmellsWithCurrentThreshold<5) return false;
     double ratio=totalRemovedSemllsWithCurrentThreshold/(double)totalSmellsWithCurrentThreshold;
         if(!THRESHOLDS.IsOurOfRange(ratio))
         {
        	return  false; //no need to adjust the threshold        	 
         }
         THRESHOLDS.setLONGPARAMETER(THRESHOLDS.AdjustThreshold(THRESHOLDS.getLONGPARAMETER(), ratio)); 
         
         //TODO 重新检查smell
         for(Smell asmell : existing)
         {
        	 if(asmell instanceof LongParameter)
        	           asmell.DetectedWithCurrentThreshold=false;
         }
         totalSmellsWithCurrentThreshold=0;
         totalRemovedSemllsWithCurrentThreshold=0;
         return true;
	}
}
