package de.ugoe.cs.swe.bnftools.ui.handler;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xml.type.SimpleAnyType;
import org.eclipse.emf.ecore.xml.type.XMLTypeFactory;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.generator.OutputConfiguration;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;

import com.google.inject.Inject;
import com.google.inject.Provider;

public class GenerationHandler extends AbstractHandler implements IHandler {
    
    @Inject
    private IGenerator generator;
 
    @Inject
    private Provider<EclipseResourceFileSystemAccess2> fileAccessProvider;
     
    @Inject
    IResourceDescriptions resourceDescriptions;
     
    @Inject
    IResourceSetProvider resourceSetProvider;
     
    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
    	String mode = "";
 
    	try {
			mode = event.getCommand().getName();
		} catch (NotDefinedException e1) {
			// catch block
			e1.printStackTrace();
		}
    		 

    	 
        ISelection selection = HandlerUtil.getCurrentSelection(event);
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection = (IStructuredSelection) selection;
            Object firstElement = structuredSelection.getFirstElement();
            if (firstElement instanceof IFile) {
                IFile file = (IFile) firstElement;
                IProject project = file.getProject();
                IFolder srcGenFolder = project.getFolder("src-gen");
                if (!srcGenFolder.exists()) {
                    try {
                        srcGenFolder.create(true, true,
                                new NullProgressMonitor());
                    } catch (CoreException e) {
                        return null;
                    }
                }
 
                final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
                fsa.setOutputPath(srcGenFolder.getFullPath().toString());
                
                //complete the filesystemaccess 
                fsa.setMonitor(new NullProgressMonitor());
                Map<String, OutputConfiguration> teste = fsa.getOutputConfigurations();
        		
                Iterator<Entry<String, OutputConfiguration>> it = teste.entrySet().iterator();
                
                while(it.hasNext()){
                	 
                    Entry<String, OutputConfiguration> next = it.next();
                    OutputConfiguration out = next.getValue();
                    out.isOverrideExistingResources();
                    out.setCreateOutputDirectory(true); // <--- do not touch this
                 
                  }
                  // ----->
                
                URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
                ResourceSet rs = resourceSetProvider.get(project);
                Resource r = rs.getResource(uri, true);
                
                // to pass a String inside a resource i have to wrap it in a EOBject
                SimpleAnyType wrapper = XMLTypeFactory.eINSTANCE.createSimpleAnyType();
                wrapper.setInstanceType(EcorePackage.eINSTANCE.getEString());
                wrapper.setValue(mode);
                //
               
                // add string to resource
                r.getContents().add(wrapper);
            
                generator.doGenerate(r, fsa);
                 
                
            }
        }
        return null;
    }
 
    @Override
    public boolean isEnabled() {
        return true;
    }
 
}