package org.eclipse.gmf.tooling.tests.xtend.rt;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.codegen.ecore.Generator;
import org.eclipse.emf.codegen.util.CodeGenUtil.EclipseUtil;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.codegen.gmfgen.ElementType;
import org.eclipse.gmf.codegen.gmfgen.GenDiagram;
import org.eclipse.gmf.codegen.gmfgen.GenNode;
import org.eclipse.gmf.codegen.gmfgen.GenTopLevelNode;
import org.eclipse.gmf.codegen.gmfgen.MetamodelType;
import org.eclipse.gmf.codegen.gmfgen.SpecializationType;
import org.eclipse.gmf.codegen.util.GMFGeneratorModule;
import org.eclipse.gmf.codegen.xtend.ui.handlers.Xtend2Emitter;
import org.eclipse.gmf.common.UnexpectedBehaviourException;
import org.eclipse.gmf.internal.common.codegen.TextEmitter;
import org.eclipse.gmf.mappings.Constraint;
import org.eclipse.gmf.mappings.FeatureSeqInitializer;
import org.eclipse.gmf.mappings.FeatureValueSpec;
import org.eclipse.gmf.mappings.GMFMapFactory;
import org.eclipse.gmf.mappings.Language;
import org.eclipse.gmf.mappings.NodeMapping;
import org.eclipse.gmf.runtime.common.core.command.ICompositeCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.tests.Utils;
import org.eclipse.gmf.tests.rt.EditHelpersTest;
import org.eclipse.gmf.tests.setup.DiaDefSource;
import org.eclipse.gmf.tests.setup.DomainModelSource;
import org.eclipse.gmf.tests.setup.GenProjectSetup;
import org.eclipse.gmf.tests.setup.GeneratedDiagramPlugin;
import org.eclipse.gmf.tests.setup.GeneratorConfiguration;
import org.eclipse.gmf.tests.setup.MapDefSource;
import org.eclipse.gmf.tests.setup.MapSetup;
import org.eclipse.gmf.tests.setup.SessionSetup;
import org.eclipse.gmf.tests.setup.ToolDefSource;
import org.eclipse.gmf.tooling.tests.xtend.setup.RuntimeBasedGeneratorConfigurationXtend;
import org.osgi.framework.BundleException;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

import edithelpers.edithelper;
import edithelpers.manifest;
import edithelpers.plugin;

public class EditHelpersTestXtend extends EditHelpersTest {

	private static final String BEFORE_PREFIX = "before";

	private static final String AFTER_PREFIX = "after";

	private static final String MARKER_COMMAND_LABEL = "MarkerCommand";

	private final static Injector injector = Guice.createInjector(new Module[]{new GMFGeneratorModule(null)});;
	
	public EditHelpersTestXtend(String name) {
		super(name, new RuntimeBasedGeneratorConfigurationXtend());
	}

	public void testSingleEditHelperAdviceNode() {
		assertTrue(getSetup().getGenModel().getNodeA().getElementType() instanceof MetamodelType);
		Command command = getSetNewTopLeveNodeNameCommand(getSetup().getGenModel().getNodeA(), getSetup().getDomainModel().getNodeA().getNameAttr().getName());
		Collection<IUndoableOperation> allMarkerCommands = getAllMarkerCommands(command);
		Collection<IUndoableOperation> beforeCommands = getBeforeCommands(allMarkerCommands);
		Collection<IUndoableOperation> afterCommands = getAfterCommands(allMarkerCommands);
		// One before and one after command should be associated with this
		// element type
		assertTrue(beforeCommands.size() == 1);
		assertTrue(getEditHelperVisualID(beforeCommands.iterator().next()) == getSetup().getGenModel().getNodeA().getVisualID());
		assertTrue(afterCommands.size() == 1);
		assertTrue(getEditHelperVisualID(afterCommands.iterator().next()) == getSetup().getGenModel().getNodeA().getVisualID());
	}

	public void testTwoEditHelperAdvicesNode() {
		assertTrue(getSetup().getGenModel().getNodeB().getElementType() instanceof SpecializationType);
		Command command = getSetNewTopLeveNodeNameCommand(getSetup().getGenModel().getNodeB(), getSetup().getDomainModel().getNodeB().getNameAttr().getName());
		Collection<IUndoableOperation> allMarkerCommands = getAllMarkerCommands(command);
		Collection<IUndoableOperation> beforeCommands = getBeforeCommands(allMarkerCommands);
		Collection<IUndoableOperation> afterCommands = getAfterCommands(allMarkerCommands);
		// Two before and two after commands should be associated with this
		// element type
		assertTrue(beforeCommands.size() == 2);
		assertTrue(hasCommand(beforeCommands, getSetup().getGenModel().getNodeA().getVisualID()));
		assertTrue(hasCommand(beforeCommands, getSetup().getGenModel().getNodeB().getVisualID()));

		assertTrue(afterCommands.size() == 2);
		assertTrue(hasCommand(afterCommands, getSetup().getGenModel().getNodeA().getVisualID()));
		assertTrue(hasCommand(afterCommands, getSetup().getGenModel().getNodeB().getVisualID()));
	}

	@Override
	protected Diagram createDiagramView(EObject domainElement, GeneratedDiagramPlugin genPlugin) {
		return RuntimeBasedGeneratorConfigurationXtend.createDiagram(domainElement, genPlugin);
	}

	private boolean hasCommand(Collection<IUndoableOperation> beforeCommands, int visualID) {
		for (IUndoableOperation operation : beforeCommands) {
			if (getEditHelperVisualID(operation) == visualID) {
				return true;
			}
		}
		return false;
	}

	private Command getSetNewTopLeveNodeNameCommand(GenNode genNode, String nameAttribute) {
		Node node = createNode(genNode, getDiagram());
		assertNotNull(node);
		EditPart nodeEditPart = getViewerConfiguration().findEditPart(node);
		assertNotNull(nodeEditPart);
		EObject nodeElement = node.getElement();
		SetRequest setReq = new SetRequest(nodeElement, nodeElement.eClass().getEStructuralFeature(nameAttribute), "newName");
		Command command = nodeEditPart.getCommand(new EditCommandRequestWrapper(setReq));
		assertNotNull(command);
		assertTrue(command.canExecute());
		return command;
	}

	private Collection<IUndoableOperation> getAllMarkerCommands(Command command) {
		if (command instanceof CompoundCommand) {
			Collection<IUndoableOperation> result = new ArrayList<IUndoableOperation>();
			for (Object object : ((CompoundCommand) command).getCommands()) {
				result.addAll(getAllMarkerCommands((Command) object));
			}
			return result;
		}
		if (command instanceof ICommandProxy) {
			ICommandProxy commandProxy = (ICommandProxy) command;
			return getAllMarkerCommands(commandProxy.getICommand());
		}
		return Collections.emptyList();
	}

	private Collection<IUndoableOperation> getAllMarkerCommands(IUndoableOperation operation) {
		if (operation instanceof ICompositeCommand) {
			ICompositeCommand compositeCommand = (ICompositeCommand) operation;
			Collection<IUndoableOperation> result = new ArrayList<IUndoableOperation>();
			for (Iterator<?> it = compositeCommand.iterator(); it.hasNext();) {
				result.addAll(getAllMarkerCommands((IUndoableOperation) it.next()));
			}
			return result;
		}
		if (isMarkerCommand(operation)) {
			return Collections.singletonList(operation);
		}
		return Collections.emptyList();
	}

	private boolean isMarkerCommand(IUndoableOperation operation) {
		String label = operation.getLabel();
		return label != null && label.indexOf(MARKER_COMMAND_LABEL) > -1;
	}

	private Collection<IUndoableOperation> getBeforeCommands(Collection<IUndoableOperation> markerCommands) {
		Collection<IUndoableOperation> result = new ArrayList<IUndoableOperation>();
		for (IUndoableOperation command : markerCommands) {
			if (isBeforeMarkerCommand(command)) {
				result.add(command);
			}
		}
		return result;
	}

	private Collection<IUndoableOperation> getAfterCommands(Collection<IUndoableOperation> markerCommands) {
		Collection<IUndoableOperation> result = new ArrayList<IUndoableOperation>();
		for (IUndoableOperation command : markerCommands) {
			if (isAfterMarkerCommand(command)) {
				result.add(command);
			}
		}
		return result;
	}

	private boolean isBeforeMarkerCommand(IUndoableOperation operation) {
		assertTrue("Should be marker operation", isMarkerCommand(operation));
		String label = operation.getLabel();
		return BEFORE_PREFIX.equals(label.substring(0, label.indexOf(MARKER_COMMAND_LABEL)));
	}

	private boolean isAfterMarkerCommand(IUndoableOperation operation) {
		assertTrue("Should be marker operation", isMarkerCommand(operation));
		String label = operation.getLabel();
		return AFTER_PREFIX.equals(label.substring(0, label.indexOf(MARKER_COMMAND_LABEL)));
	}

	private int getEditHelperVisualID(IUndoableOperation operation) {
		assertTrue("Should be marker operation", isMarkerCommand(operation));
		String label = operation.getLabel();
		return Integer.valueOf(label.substring(label.indexOf(MARKER_COMMAND_LABEL) + MARKER_COMMAND_LABEL.length()));
	}

	public static final class EditHelpersSessionSetup extends SessionSetup {

		public EditHelpersSessionSetup() {
			super(new RuntimeBasedGeneratorConfigurationXtend());
		}

		@Override
		protected DomainModelSource createDomainModel() {
			return new EditHelpersModelSource();
		}

		@Override
		protected GenProjectSetup createGenProject(GeneratorConfiguration generatorConfiguration) throws BundleException {
			return new EditHelpersProjectSetup(generatorConfiguration).init(getGenModel());
		}

		@Override
		public MapDefSource createMapModel() {
			return new EditHelpersMapSetup().init(getGraphDefModel(), getDomainModel(), getToolDefModel());
		}
	}

	private static final class EditHelpersMapSetup extends MapSetup {

		@Override
		public MapSetup init(DiaDefSource ddSource, DomainModelSource domainSource, ToolDefSource toolDef) {
			super.init(ddSource, domainSource, toolDef);
			addConstraint(getNodeA(), "nodeName2.oclIsUndefined()");
			addNameInitializer(getNodeA(), domainSource.getNodeA().getNameAttr(), "'name'");
			addConstraint(getNodeB(), "nodeName1.oclIsUndefined()");
			addNameInitializer(getNodeB(), domainSource.getNodeB().getNameAttr(), "'name'");
			return this;
		}

		private void addConstraint(NodeMapping node, String body) {
			node.setDomainSpecialization(GMFMapFactory.eINSTANCE.createConstraint());
			node.getDomainSpecialization().setLanguage(Language.OCL_LITERAL);
			node.getDomainSpecialization().setBody(body);
		}

		private void addNameInitializer(NodeMapping node, EStructuralFeature feature, String value) {
			FeatureSeqInitializer root = GMFMapFactory.eINSTANCE.createFeatureSeqInitializer();
			node.setDomainInitializer(root);
			FeatureValueSpec nameSpecification = GMFMapFactory.eINSTANCE.createFeatureValueSpec();
			root.getInitializers().add(nameSpecification);
			nameSpecification.setFeature(feature);
			Constraint valueExpr = GMFMapFactory.eINSTANCE.createConstraint();
			nameSpecification.setValue(valueExpr);
			valueExpr.setBody(value);
			valueExpr.setLanguage(Language.OCL_LITERAL);
		}

	}

	private static final class EditHelpersProjectSetup extends GenProjectSetup {

		private String myBundleName;

		
		
		private EditHelpersProjectSetup(GeneratorConfiguration generatorFactory) {
			super(generatorFactory);
		}

		@Override
		protected void generateDiagramPrerequisites(GenDiagram d) throws Exception {
			super.generateDiagramPrerequisites(d);
			generateEditHelpersProject(d);
		}

		private void generateEditHelpersProject(GenDiagram d) {
			myBundleName = Utils.createUniquePluginID() + ".edithelpers";
			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(myBundleName);
			final Path srcPath = new Path('/' + project.getName() + "/src"); //$NON-NLS-1$
			final int style = Generator.EMF_PLUGIN_PROJECT_STYLE;
			final List<?> pluginVariables = null;
			Generator.createEMFProject(srcPath, null, Collections.<IProject> emptyList(), new NullProgressMonitor(), style, pluginVariables);
			createManifestMF();
			for (GenTopLevelNode node : d.getTopLevelNodes()) {
				createEditHelper(node);
			}
			createPluginXML(d);
			projectsToInit.add(myBundleName);
		}
		
		public void createManifestMF() {
			Xtend2Emitter emiter = new Xtend2Emitter(injector, manifest.class, "main");
			doGenerateFile(emiter, new Path("/" + myBundleName + "/META-INF/MANIFEST.MF"), myBundleName);
		}

		public void createEditHelper(GenTopLevelNode node) {
			ElementType elementType = node.getElementType();
			if (elementType == null) {
				return ;
			}
			String className;
			if (elementType instanceof MetamodelType) {
				className = ((MetamodelType) elementType).getEditHelperClassName() + "ExternalAdvice";
			} else if (elementType instanceof SpecializationType) {
				String adviceClassName = ((SpecializationType) elementType).getEditHelperAdviceClassName();
				if (adviceClassName == null || adviceClassName.trim().length() ==0) {
					// advice class name is usually empty, as we do not generate anything reasonable inside them,
					// hence, need to identify SpecializationType differently
					adviceClassName = node.getUniqueIdentifier();
				}
				className = adviceClassName + "ExternalAdvice";
			} else {
				return;
			}
			Xtend2Emitter emiter = new Xtend2Emitter(injector, edithelper.class, "main");
			doGenerateFile(emiter, new Path("/" + myBundleName + "/src/" + className + ".java"), elementType);
		}

		public void createPluginXML(GenDiagram d) {
			Xtend2Emitter emiter = new Xtend2Emitter(injector, plugin.class, "main");
			doGenerateFile(emiter, new Path("/" + myBundleName + "/plugin.xml"), d);
		}

		private void doGenerateFile(TextEmitter emitter, IPath filePath, Object... param) {
			try {
				IPath containerPath = filePath.removeLastSegments(1);
				EclipseUtil.findOrCreateContainer(containerPath, false, (IPath) null, new NullProgressMonitor());
				String genText = emitter.generate(new NullProgressMonitor(), param);
				IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
				f.create(new ByteArrayInputStream(genText.getBytes(f.getCharset())), true, new NullProgressMonitor());
			} catch (InvocationTargetException ex) {
				fail(ex.getMessage());
			} catch (UnexpectedBehaviourException ex) {
				fail(ex.getMessage());
			} catch (CoreException ex) {
				fail(ex.getMessage());
			} catch (UnsupportedEncodingException ex) {
				fail(ex.getMessage());
			} catch (InterruptedException ex) {
				fail(ex.getMessage());
			}
		}
	}

	private static final class EditHelpersModelSource implements DomainModelSource {

		private EClass myDiagramElement;

		private EPackage myPackage;

		private NodeData myNode1;

		private LinkData myClassLink;

		private NodeData myNode2;

		private EReference myRefLink;
		{
			myPackage = EcoreFactory.eINSTANCE.createEPackage();
			myPackage.setName("eh");
			myPackage.setNsPrefix("sampleEH");
			Calendar c = Calendar.getInstance();
			myPackage.setNsURI("uri://eclipse/gmf/tests/sample/eh/" + c.get(Calendar.HOUR_OF_DAY) + '/' + c.get(Calendar.MINUTE) + '/');

			myDiagramElement = EcoreFactory.eINSTANCE.createEClass();
			myDiagramElement.setName("DiagramElement");
			myPackage.getEClassifiers().add(myDiagramElement);

			EClass node = EcoreFactory.eINSTANCE.createEClass();
			node.setName("Node");
			myPackage.getEClassifiers().add(node);
			EAttribute node1Name = EcoreFactory.eINSTANCE.createEAttribute();
			node1Name.setName("nodeName1");
			node1Name.setEType(EcorePackage.eINSTANCE.getEString());
			node.getEStructuralFeatures().add(node1Name);
			EAttribute node2Name = EcoreFactory.eINSTANCE.createEAttribute();
			node2Name.setName("nodeName2");
			node2Name.setEType(EcorePackage.eINSTANCE.getEString());
			node.getEStructuralFeatures().add(node2Name);

			EReference nodeContainment = EcoreFactory.eINSTANCE.createEReference();
			nodeContainment.setName("nodeContainment");
			nodeContainment.setContainment(true);
			nodeContainment.setUpperBound(-1);
			nodeContainment.setEType(node);
			myDiagramElement.getEStructuralFeatures().add(nodeContainment);

			EClass classLink = EcoreFactory.eINSTANCE.createEClass();
			classLink.setName("Link");
			myPackage.getEClassifiers().add(classLink);

			EReference linkContainment = EcoreFactory.eINSTANCE.createEReference();
			linkContainment.setName("linkContainment");
			linkContainment.setEType(classLink);
			linkContainment.setUpperBound(-1);
			linkContainment.setContainment(true);
			node.getEStructuralFeatures().add(linkContainment);

			EReference linkTarget = EcoreFactory.eINSTANCE.createEReference();
			linkTarget.setName("target");
			linkTarget.setEType(node);
			linkTarget.setUpperBound(1);
			classLink.getEStructuralFeatures().add(linkTarget);

			myRefLink = EcoreFactory.eINSTANCE.createEReference();
			myRefLink.setName("refLink");
			myRefLink.setEType(node);
			myRefLink.setUpperBound(-1);
			node.getEStructuralFeatures().add(myRefLink);

			new ResourceImpl(URI.createURI("uri://org.eclipse.gmf.eh/tests/DomainModelSetup")).getContents().add(myPackage);

			myNode1 = new NodeData(node, node1Name, nodeContainment);
			myNode2 = new NodeData(node, node2Name, nodeContainment);
			myClassLink = new LinkData(classLink, linkTarget, linkContainment);
		}

		public EClass getDiagramElement() {
			return myDiagramElement;
		}

		public LinkData getLinkAsClass() {
			return myClassLink;
		}

		public EReference getLinkAsRef() {
			return myRefLink;
		}

		public EPackage getModel() {
			return myPackage;
		}

		public NodeData getNodeA() {
			return myNode1;
		}

		public NodeData getNodeB() {
			return myNode2;
		}
	}

}
