/*
 * This file has been developed at the University of Munich, Chair for Programming & Software Engineering.
 * 
 * This file is licensed under the Eclipse Public License (EPL) 1.0
 * 
 */
package eu.mdd4soa.trans.smm2java.actions;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.generation.files.Generate_JavaStructures;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;

import eu.mdd4soa.smm.exception.InvalidSetupException;
import eu.mdd4soa.smm.exception.TransformationException;
import eu.mdd4soa.smm.statik.Participant;
import eu.mdd4soa.trans.smm2java.EMFUtil;
import eu.mdd4soa.trans.smm2java.SMM2JavaPlugin;
import eu.mdd4soa.trans.smm2java.impl.SMM2JavaTransformer;

public class ConvertSMM2JavaAction implements IObjectActionDelegate {

	private IWorkbenchPart fWorkbenchPart;

	private IFile fSelectedFile;

	@Override
	public void run(IAction action) {

		try {
			if (fSelectedFile == null) {
				MessageDialog.openError(getShell(), "No File", "Attempt to run conversion without a file -- exiting");
				return;
			}

			Participant participant= EMFUtil.loadParticipant(fSelectedFile);
			IProject project= fSelectedFile.getProject();

			convertToJava(project, participant);

		} catch (InvalidSetupException e) {
			SMM2JavaPlugin.logError("Cannot load input SMM XMI", e);
			MessageDialog.openError(getShell(), "SMM2Java", "Cannot load input SMM XMI: " + e.getMessage());

		} catch (CoreException e) {
			SMM2JavaPlugin.logError("Problem accessing workspace target directory", e);
			MessageDialog.openError(getShell(), "SMM2Java", "Problem accessing workspace target directory: " + e.getMessage());
		} catch (IOException e) {
			SMM2JavaPlugin.logError("Could not write to destination", e);
			MessageDialog.openError(getShell(), "SMM2Java", "Could not write out destination files: " + e.getMessage());
		} catch (TransformationException e) {
			SMM2JavaPlugin.logError("Problem transforming to Java", e);
			MessageDialog.openError(getShell(), "SMM2Java", "Problem transforming to Java: " + e.getMessage());
		}
	}

	public static void convertToJava(IProject project, Participant participant) throws CoreException, TransformationException, IOException {
		// Get or create source folder.

		IFolder srcFolder= project.getFolder("src");

		if (srcFolder == null || !srcFolder.exists())
			srcFolder.create(true, true, new NullProgressMonitor());

		File targetSrcFolder= srcFolder.getRawLocation().toFile();


		Model javaModel= SMM2JavaTransformer.execute(participant);

		ResourceSet rs= new ResourceSetImpl();
		Resource r= new XMIResourceImpl();
		rs.getResources().add(r);

		r.getContents().add(javaModel);

		r.setURI(URI.createFileURI(srcFolder.getFile(participant.getName() + ".javaxmi").getFullPath().toString()));
		r.save(null);

		Generate_JavaStructures javaGenerator;
		javaGenerator= new Generate_JavaStructures(javaModel, targetSrcFolder, new ArrayList<Object>());
		javaGenerator.doGenerate(null);

		srcFolder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
	}

	@Override
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		fWorkbenchPart= targetPart;
	}

	@Override
	public void selectionChanged(IAction action, ISelection selection) {
		if (selection == null || ! (selection instanceof StructuredSelection) && ( ((StructuredSelection) selection).isEmpty()))
			fSelectedFile= null;
		else {
			Object element= ((StructuredSelection) selection).getFirstElement();
			if (element instanceof IFile)
				fSelectedFile= (IFile) element;
			else
				fSelectedFile= null;
		}
	}

	private Shell getShell() {
		return fWorkbenchPart.getSite().getShell();
	}

}
