package Smells;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eposoft.jccd.data.ast.ANode;

import cleman.Main;

import Analysis.printer;
import Detectors.Diff;
import Detectors.THRESHOLDS;

public class Duplicatedcode extends Smell {
	
	public static int totalNoOfDetectorSmells=0;
	public static int totalNoOfDisparedSmells=0;
	public static String filelocation;
	String Suggestion="Extarct as a common method (Menu Refactor-->Extract Method)";
	public static ANode filenode;
	private static int doubleClickNum=-1;
	public ArrayList<DuplicatedInfo> infos=new ArrayList<DuplicatedInfo>();
	public String getSuggestion()
	{
		return Suggestion;
		
		
	}
	
	private ArrayList<DuplicatedInfo> nodes = null;
	public DuplicatedInfo editingnode;
	public String name;
	public String thestring=null;
	public ArrayList<DuplicatedInfo> get()
	{return nodes ;}
	public ArrayList<DuplicatedInfo> addNode(ArrayList<DuplicatedInfo> nodes)
	{   ArrayList<DuplicatedInfo> newnodes=nodes;
		
		return newnodes;}
	
	public void GenExplainnation() {

         //   return this.explaination;
	}
	
	public IFile getIFile() {
		IFile file=null;
		try{
			if(doubleClickNum<0)
				doubleClickNum=0;
			else
				doubleClickNum++;
			IProject[] allProjects=ResourcesPlugin.getWorkspace().getRoot().getProjects();
		
		String projectPath=""; 
		for(IProject project: allProjects)
		 {
			 if(!Main.projectName.equalsIgnoreCase(project.getName()))
					 continue;
			   projectPath=project.getFullPath().toString();
			   break;
		 }
		IPath path=new  Path(projectPath+"/"+Main.trunkDir+"/"+getFileLocation());
		file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
	}catch (Exception e)
	{
		
	}
		
		return file;
	}
	private String getFileLocation()
	{
	
		int index=doubleClickNum % infos.size();
		return infos.get(index).filename;

		
	}

	public  static void AdjustThresholdAfterStatistics()
	{
		double RATION;
		if(totalNoOfDetectorSmells<=10)return;
		
	 RATION=totalNoOfDisparedSmells/totalNoOfDetectorSmells;
		if(! THRESHOLDS.IsOurOfRange( RATION))
		{ THRESHOLDS.Duplicatedline=THRESHOLDS.AdjustThreshold(THRESHOLDS.Duplicatedline,  RATION);}
		totalNoOfDetectorSmells=0;
		totalNoOfDisparedSmells=0;
		
	}
	public void save(BufferedWriter bw){}
//	{   
//	   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);
//			 getstring();
//			 String strh= Integer.toString( editingnode.Starth);
//			 String strl= Integer.toString( editingnode.Startl);
//			 String endh=Integer.toString( editingnode.Endh);
//			 String endl=Integer.toString( editingnode.Endl);
//			 bw.append(strh);
//			 bw.append(".");
//			 bw.append(strl);
//			 bw.append("--");
//			 bw.append(endh);
//			 bw.append(".");
//			 bw.append(endl);
//			 
//			 
//			 
//			
//			
//		}catch(Exception e) {
//  	     printer.print(e); }
//		
//		
//	}
	
	public void forcomparation(){}
//	{
//		String strh= Integer.toString(  editingnode.Starth);
//		
//		 String strl= Integer.toString( editingnode.Startl);
//		 
//		 String endh=Integer.toString( editingnode.Endh);
//		 String endl=Integer.toString( editingnode.Endl);
//		
//		 String m=(strh+"."+strl+"--"+endh+"."+endl);
//		 forcompareted=m;
//			
//		}
//	
	
	
	
//	public void getstring()
//	{
//		int totallength = 0;
//		String Sname=editingnode.filename;
//		File file = new File(Sname);
//		if (file.exists() && file.isFile()) {
//			try {
//
//				BufferedReader input = new BufferedReader(new FileReader(file));
//				int j = editingnode.Starth;
//				int i = 1;
//				String text;
//				for (; i < j; i++) {
//					
//					text = input.readLine();
//					totallength += text.length()+2;
//				}
//			   int t = editingnode.Endh;
//			   totallength = 0; 
//			   
//			   for (; i < t; i++) {
//					
//					text = input.readLine();
//					totallength += text.length()+2;
//					thestring=thestring+text;
//				}
//			   length = totallength + editingnode.Endl - editingnode.Startl+1;
//				String lasth;
//				lasth=input.readLine().toString().substring(1, editingnode.Endl);
//				thestring=thestring+lasth;
//				int a1=editingnode.Startl;
//				//int a2=length;
//				
//			     thestring=thestring.substring(a1);
//				
//				
//
//				input.close();
//				
//			}
//			catch (IOException ioException) {
//				System.err.println("File Error!");
//			}
//
//		
//		
//		}
//		
//		
//	}
//	
	
	
	
	
	
	public int getStartPoint() {

		
		int index=doubleClickNum % infos.size();
		return infos.get(index).StartChart;
	//	return this.startPoint;
	}
	public int getLength() {
		int index=doubleClickNum % infos.size();
		return infos.get(index).lengthinChart;
	}
//	public int read(String name) {
//		
//		File file = new File(name);
//		int totallength = 0;
//		
//		if (file.exists() && file.isFile()) {
//			try {
//
//				BufferedReader input = new BufferedReader(new FileReader(file));
//				
//
//				int j = editingnode.Starth;
//				int i = 1;
//
//				for (; i < j; i++) {
//					String text;
//					text = input.readLine();
//					totallength += text.length()+2;
//				}
//				startPoint = totallength + editingnode.Startl+1;
//				//System.out.print("开始位置" + startPoint);
//				int t = editingnode.Endh;
//				totallength = 0;
//				String text;
//				for (; i < t; i++) {
//					
//					text = input.readLine();
//					totallength += text.length()+2;
//					
//				}
//				
//				length = totallength + editingnode.Endl - editingnode.Startl+1;
//
//				//System.out.println(length);
//			
//
//				input.close();
//			}
//
//			catch (IOException ioException) {
//				System.err.println("File Error!");
//			}
//
//		}
//		return totallength;
//
//	}

	public void append(DuplicatedInfo node) {

		nodes.add(node);

	}

	public Duplicatedcode() {
		setType(SMELLTYPE.DUPLICATEDCODE);
		nodes = new ArrayList<DuplicatedInfo>();
	}

	public boolean Smellequal(Smell obj) {
		if (!(obj instanceof Duplicatedcode))
			return false;
		Duplicatedcode target = (Duplicatedcode) obj;
		if (target == null)
			return false;
		// if(target.unit!=this.unit) return false;
		if (target.getType() != this.getType())
			return false;
		//target.getStartPoint();
		String targetName=target.editingnode.filename;
		String thisname=this.editingnode.filename;
		String thisText = null;
		String targetText = null;
		File file = new File(thisname);
	
		if (file.exists() && file.isFile()) {
			try {

				BufferedReader input = new BufferedReader(new FileReader(file));
			//	int j = this.editingnode.Starth;
				int j=0;
				int i = 1;
                for (; i < j; i++) {
					
					 input.readLine();
					
				}
				int t = this.editingnode.Endh;
				for (; i < t; i++) {
					
					thisText = thisText+input.readLine();
										
				}

				input.close();
			}

			catch (IOException ioException) {
				System.err.println("File Error!");
			}

	   	}
			File file2 = new File(targetName);
	
			if (file.exists() && file.isFile()) {
				try {

					BufferedReader input = new BufferedReader(new FileReader(file2));
					//int j = target.editingnode.Starth;
					int j=0;
					int i = 1;
                    for (; i < j; i++) {
						
						 input.readLine();
						
					}
					int t = target.editingnode.Endh;
					for (; i < t; i++) {
						
						targetText =targetText+ input.readLine();
											
					}
				    input.close();
					

					

					
				}

				catch (IOException ioException) {
					System.err.println("File Error!");
				}

			}
			
		String code1 = thisText; 
		String code2=targetText;
		ArrayList charArray = new ArrayList();
		ArrayList charArrayA = new ArrayList();
//		System.out.println("$$$$$$$$"+code1);
//		System.out.println("@@@@@@@@"+code2);
		for (int i = 0; i < code1.length(); i++) {
			charArray.add(code1.charAt(i));
		}

		for (int i = 0; i < code2.length(); i++) {
			charArrayA.add(code2.charAt(i));
		}

	    Diff diff = new Diff(charArray,charArrayA);
		diff.diff();
		int totalDiff = diff.AmoutofDiffernce();
		double ratio = totalDiff
				/ ((double) code1.length() + (double) code2.length());
	//System.out.println("ratio=="+ratio);
		if(ratio<THRESHOLDS.RATIO)return true;
		

		return false;
		// TODO Auto-generated method stub


		
		
			}
	
	
	
	
	
	
	

	private static int totalSmellsWithCurrentThreshold = 0;
	private static int totalRemovedSemllsWithCurrentThreshold = 0;

	public void toBeRmoved() {
		if (this.DetectedWithCurrentThreshold) {
			totalRemovedSemllsWithCurrentThreshold++;
		}
	}

	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 == 0)
			return false;
		double ratio = totalRemovedSemllsWithCurrentThreshold
				/ (double) totalSmellsWithCurrentThreshold;
		if (!THRESHOLDS.IsOurOfRange(ratio)) {
			return false; // no need to adjust the threshold
		}
		THRESHOLDS.Duplicatedline = THRESHOLDS.AdjustThreshold(
				THRESHOLDS.Duplicatedline, ratio);

		// TODO 重新检查smell
		for (Smell asmell : existing) {
			if (asmell instanceof Duplicatedcode)
				asmell.DetectedWithCurrentThreshold = false;
		}
		totalSmellsWithCurrentThreshold = 0;
		totalRemovedSemllsWithCurrentThreshold = 0;
		return true;
	}
}
