package cucumber.eclipse.editor.nature;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;

import cucumber.eclipse.editor.builder.CucumberGherkinBuilder;
import cucumber.eclipse.editor.builder.CucumberStepDefinitionsBuilder;
import cucumber.eclipse.steps.integration.builder.BuilderUtil;
import cucumber.eclipse.steps.integration.marker.MarkerFactory;

public class CucumberProjectNature implements IProjectNature {
	
	public static final String ID = "cucumber.eclipse.nature";
	
    private IProject project;
    
    @Override
    public void configure() throws CoreException {
    	IProjectDescription description = project.getDescription();
	    String[] oldNatures = description.getNatureIds();
	    String[] newNatures = new String[oldNatures.length+1];
	    newNatures[0] = CucumberProjectNature.ID;
	    for (int it=0; it<oldNatures.length; it++) {
	    	String nature = oldNatures[it];
			if(CucumberProjectNature.ID.equals(nature)) {
				return ; // change nothing
			}
			newNatures[it+1] = nature;
		}
	    description.setNatureIds(newNatures);
	    project.setDescription(description, new NullProgressMonitor());
	    MarkerFactory.INSTANCE.cleanCucumberNatureMissing(project);
    	
        addBuilder(project);
        BuilderUtil.buildProject(project, IncrementalProjectBuilder.FULL_BUILD);
    }

    public void deconfigure() throws CoreException {
    	removeBuilder(project);
    	MarkerFactory.INSTANCE.cleanMarkersRecursively(project);
    }

    public IProject getProject() {
        return project;
    }

    public void setProject(IProject project) {
        this.project = project;
    }

    private void addBuilder(IProject projectToUpdate) throws CoreException {
        IProjectDescription description = projectToUpdate.getDescription();
        
        // Avoid using a Set since ICommand does not have 
        // a hash + equalTo methods to avoid duplicates
        // So we will filter by id
        Map<String, ICommand> builders = new LinkedHashMap<String, ICommand>(description.getBuildSpec().length + 1);
        for (ICommand builder : description.getBuildSpec()) {
			builders.put(builder.getBuilderName(), builder);
		}
        
        // First build step definitions
        ICommand stepDefinitionsBuilder = description.newCommand();
        stepDefinitionsBuilder.setBuilderName(CucumberStepDefinitionsBuilder.ID);
        builders.put(stepDefinitionsBuilder.getBuilderName(), stepDefinitionsBuilder);
        
        // Then build gherkins
        ICommand gherkinBuilder = description.newCommand();
        gherkinBuilder.setBuilderName(CucumberGherkinBuilder.ID);
        builders.put(gherkinBuilder.getBuilderName(), gherkinBuilder);
        
        description.setBuildSpec(builders.values().toArray(new ICommand[builders.size()]));
        projectToUpdate.setDescription(description, new NullProgressMonitor());
    }
    
    private void removeBuilder(IProject project) throws CoreException {
    	IProjectDescription description = project.getDescription();
    	Set<ICommand> builders = new LinkedHashSet<ICommand>(Arrays.asList(description.getBuildSpec()));

    	Set<ICommand> toRemove = new HashSet<ICommand>();
        for (ICommand builder : builders) {
			if(CucumberStepDefinitionsBuilder.ID.equals(builder.getBuilderName())) {
				toRemove.remove(builder);
			}
		}
        builders.removeAll(toRemove);
        
        description.setBuildSpec(builders.toArray(new ICommand[builders.size()]));
        
        project.setDescription(description, new NullProgressMonitor());
    }
}


@@ -55,148 +55,43 @@
 til.
-Arrays;%0Aimport java.util.HashSet;%0Aimport java.util.LinkedHashMap;%0Aimport java.util.LinkedHashSet;%0Aimport java.util.Map;%0Aimport java.util.Set
+LinkedHashMap;%0Aimport java.util.Map
 ;%0A%0Ai
@@ -3374,28 +3374,24 @@
 );%0A    %09
-Set%3C
 ICommand
 %3E builde
@@ -3386,63 +3386,23 @@
 mand
-%3E
+%5B%5D
  build
-ers = new LinkedHashSet%3CICommand%3E(Arrays.asList(
+Spec = 
 desc
@@ -3427,30 +3427,23 @@
 ec()
-))
 ;%0A
-%0A
     %09
-Set%3C
 ICommand
 %3E to
@@ -3442,54 +3442,83 @@
 mand
-%3E toRemove = new HashSet%3CICommand%3E();%0A        
+%5B%5D newBuildSpec = new ICommand%5BbuildSpec.length-2%5D;%0A%0A    %09int it = 0;%0A    %09
 for 
@@ -3546,21 +3546,47 @@
 uild
-ers
+Spec
 ) %7B%0A%09%09%09
-if(
+boolean isCucumberBuilder = 
 Cucu
@@ -3651,97 +3651,166 @@
 e())
-) %7B
 %0A%09%09%09%09
-toRemove.remove(builder);%0A%09%09%09%7D%0A%09%09%7D%0A        builders.removeAll(toRemove);%0A 
+%09%7C%7C CucumberGherkinBuilder.ID.equals(builder.getBuilderName()); %0A    %09%09if(!isCucumberBuilder) %7B%0A    %09%09%09newBuildSpec%5Bit++%5D = builder;%0A    %09%09%7D%0A%09%09%7D%0A
        
+ 
 %0A   
@@ -3843,55 +3843,20 @@
 pec(
-builders.toArray(new ICommand%5Bbuilders.size()%5D)
+newBuildSpec
 );%0A 

Remove the cucumber gherkin builder when a project lost the cucumber nature