package Analysis;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import monitor.views.Information;
import monitor.views.SmellComparator;


import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;

import org.eclipse.jdt.core.JavaCore;

import org.eclipse.swt.widgets.Display;

import Detectors.CommonMethodsDector;
import Detectors.DataClassDector;
import Detectors.DuplicatedCodeDector;

import Detectors.BadNameDector;
import Detectors.LargeClassDector;
import Detectors.LongMethodDector;
import Detectors.LongParameterDector;
import Detectors.PublicFielDector;
import Detectors.THRESHOLDS;
import Detectors.VisitorOfAST;
import Smells.Commonmethod;
import Smells.DataClass;
import Smells.Duplicatedcode;
import Smells.LargeClass;
import Smells.LongMethod;
import Smells.LongParameter;
import Smells.Smell;
import Analysis.ResourceVistor;

public class ManagerOfDetectors {
	public static List<Smell> SmellList = new ArrayList<Smell>();

	public static CompilationUnit unit;
	public static IResource resource;
	public boolean recover;
	public static String resourcelocation;
    public static boolean bool=true;
	public ManagerOfDetectors() {
		SmellList = new ArrayList<Smell>();
	}

	
	public List<Smell> DetectSmellsOnResource(IResource m_resource) {
		resource = m_resource;

		resourcelocation = resource.getLocation().toString();

		// 1. 构造一个AST先。
		try {

			IJavaElement javaElement = JavaCore.create(resource);

			ASTParser parser = ASTParser.newParser(AST.JLS3);
			ICompilationUnit Iunit = (ICompilationUnit) javaElement;
			if (Iunit == null) {

				return null;
			}
			parser.setSource(Iunit);
			unit = (CompilationUnit) parser.createAST(null);
			
			 
			  Information Info=new Information();
			 
			thread();

		}

		catch (Exception e) {
			printer.println(e);
		}

		if (ResListener.SmellList == null)
			ResListener.SmellList = SmellList;
		return ResListener.SmellList;
	}

	void thread() {

		Job job = new Job("test") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {

				doExpensiveWork(monitor);

				syncWithUI();

				return org.eclipse.core.runtime.Status.OK_STATUS;
			}

		};
		job.setUser(false);
		job.schedule();

	}

	public static void doExpensiveWork(IProgressMonitor monitor) {

		try {
			Date time = new Date();
			long t1 = time.getTime();
			LargeClassDector largeClass = new LargeClassDector(resource, unit);// 监测LargeClass类
			SmellList.addAll(0, largeClass.DetectSmells());
			Date time2 = new Date();// 列表中添加
			long t2 = time2.getTime();
		
			LongMethodDector longmethod = new LongMethodDector(resource, unit);
			SmellList.addAll(0, longmethod.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		
			DataClassDector dataClass = new DataClassDector(resource, unit);
			SmellList.addAll(0, dataClass.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		
			LongParameterDector longPar = new LongParameterDector(resource,
					unit);
			SmellList.addAll(0, longPar.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		

			VisitorOfAST BadName = new VisitorOfAST();
			unit.accept(BadName);
			SmellList.addAll(0, BadName.getBadName(resource, unit));
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		  

			VisitorOfAST BadParameterName = new VisitorOfAST();
			unit.accept(BadParameterName);
			SmellList.addAll(0, BadParameterName.getBadName2(resource, unit));
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
			

			BadNameDector badname = new BadNameDector(resource, unit);
			SmellList.addAll(0, badname.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
	

			PublicFielDector pubField = new PublicFielDector(resource, unit);
			SmellList.addAll(0, pubField.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		
			CommonMethodsDector commonmethod = new CommonMethodsDector(
					resource, unit);
			SmellList.addAll(0, commonmethod.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		

			VisitorOfAST smellVisitor = new VisitorOfAST();
			unit.accept(smellVisitor);
			SmellList.addAll(0, smellVisitor.getSwitchSmells(resource, unit));
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
			

			DuplicatedCodeDector duplicatedCode = new DuplicatedCodeDector(
					resource, unit);
			SmellList.addAll(0, duplicatedCode.DetectSmells());
			time2 = new Date();// 列表中添加
			t2 = time2.getTime();
		
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void syncWithUI() {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
			

				if (ResListener.SmellList == null) {
					ResListener.SmellList = new ArrayList<Smell>();

				}
				SmellList = ResListener.SmellList = Smell.removeDuplicated(
						ResListener.SmellList, SmellList);
				LongParameter.AdjustThresholdAfterStatistics();
				Commonmethod.AdjustThresholdAfterStatistics();
				DataClass.AdjustThresholdAfterStatistics();
				LargeClass.AdjustThresholdAfterStatistics();
				LongMethod.AdjustThresholdAfterStatistics();
				Duplicatedcode.AdjustThresholdAfterStatistics();

				ResListener.SmellList = SmellList;
				Collections.sort(ResListener.SmellList, new SmellComparator());
				ResListener.viewer.setInput(ResListener.SmellList);
		
				ResListener.viewer.refresh();
				ResourceVistor.ChangeColor(ResListener.viewer.getTable());
				ResListener.viewer.refresh();

				return;

			}

		});
	}
}
