/*******************************************************************************
 * Copyright (c) 2016, 2019 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.umlx.tests;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.URIHandler;
import org.eclipse.emf.ecore.resource.impl.FileURIHandlerImpl;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.internal.utilities.OCLInternal;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.TreeIterable;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.QVTbaseFactory;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbase;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.QVTrelationFactory;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.TemplateVariable;
import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelation;
import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
import org.eclipse.qvtd.umlx.qvtr2umlx.QVTr2UMLX;
import org.eclipse.qvtd.umlx.umlx2qvtr.UMLX2QVTr;
import org.eclipse.qvtd.umlx.utilities.UMLXStandaloneSetup;
import org.eclipse.qvtd.xtext.qvtbase.tests.LoadTestCase;
import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.TestsXMLUtil;
import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.XtextCompilerUtil;

import com.google.common.collect.Lists;

/**
 * Tests that load a model and verify that there are no unresolved proxies as a result.
 */
public class UMLXSerializeTests extends LoadTestCase
{
	@Override
	protected @NonNull OCLInternal createOCL() {
		return QVTbase.newInstance(getTestProjectManager(), null);
	}

	/*	protected void doLoad_QVTr(URI inputURI, URI pivotURI) throws IOException {
		OCL ocl = OCL.newInstance(getProjectMap());
		doLoad_Concrete(ocl, inputURI, pivotURI, null);
		ocl.dispose();
	} */

	protected void doLoadTest(URI inputURI, URI pivotURI, URI umlxURI) throws Exception {
		OCL ocl = OCL.newInstance(getTestProjectManager());
		Resource qvtrResource = doLoad_Concrete(ocl, inputURI, pivotURI, null);
		Resource umlxResource = qvtrResource.getResourceSet().createResource(umlxURI);
		QVTr2UMLX qvtr2umlx = new QVTr2UMLX(ocl.getEnvironmentFactory(), qvtrResource, umlxResource);
		qvtr2umlx.transform();
		umlxResource.save(null);
		//
		assertNoValidationErrors(umlxURI.toString(), umlxResource);
		//
		ocl.dispose();
	}

	protected void doRoundTripTest(@NonNull String path, @NonNull String stem, boolean skipCompare) throws Exception {
		QVTrelation ocl1 = QVTrelation.newInstance(getTestProjectManager());
		URI inputURI1 = getResourceURI(path + stem + ".qvtr");
		URI pivotURI1 = getTestURI(stem + ".qvtras");
		URI umlxURI = getTestURI(path + stem + ".umlx");
		URI pivotURI2 = getTestURI(stem + ".regenerated.qvtras");

		URIConverter uriConverter = ocl1.getResourceSet().getURIConverter();
		URI normalizedURI = uriConverter.normalize(umlxURI);
		URIHandler uriHandler = uriConverter.getURIHandler(normalizedURI);
		if (!(uriHandler instanceof FileURIHandlerImpl)) {		// platform:/plugin on Hudson
			umlxURI = getTestURI(stem + ".umlx");
		}

		Resource qvtrResource1 = doLoad_Concrete(ocl1, inputURI1, pivotURI1, null);
		Resource umlxResource1 = qvtrResource1.getResourceSet().createResource(umlxURI);
		QVTr2UMLX qvtr2umlx = new QVTr2UMLX(ocl1.getEnvironmentFactory(), qvtrResource1, umlxResource1);
		qvtr2umlx.transform();
		umlxResource1.save(null);
		//
		assertNoValidationErrors(umlxURI.toString(), umlxResource1);
		//
		QVTrelation ocl2 = QVTrelation.newInstance(getTestProjectManager());
		Resource umlxResource2 = ocl2.getResourceSet().getResource(umlxURI, true);
		Resource qvtrResource2 = ocl2.getMetamodelManager().getASResourceSet().createResource(pivotURI2);
		UMLX2QVTr umlx2qvtr = new UMLX2QVTr(ocl2.getEnvironmentFactory(), umlxResource2, qvtrResource2);
		umlx2qvtr.transform();
		qvtrResource2.save(CompilerUtil.defaultSavingOptions);
		//
		Model asModel1 = PivotUtil.getModel(qvtrResource1);
		Model asModel2 = PivotUtil.getModel(qvtrResource2);
		asModel2.setName(asModel1.getName());
		asModel2.setExternalURI(asModel1.getExternalURI());
		TestsXMLUtil.resetTransients(qvtrResource1);
		TestsXMLUtil.resetTransients(qvtrResource2);
		normalize(qvtrResource1);
		normalize(qvtrResource2);
		if (!skipCompare) {				// FIXME BUG 511230
			assertSameModel(qvtrResource1, qvtrResource2);
		}
		ocl1.dispose();
		ocl2.dispose();
	}

	private void normalize(@NonNull Resource qvtrResource) {
		for (TreeIterator<EObject> tit = qvtrResource.getAllContents(); tit.hasNext(); ) {
			EObject eObject = tit.next();
			if (eObject instanceof Relation) {
				normalizeRelation((Relation)eObject);
				tit.prune();
			}
			else if (eObject instanceof Import) {
				((Import)eObject).getOwnedComments().clear();
				tit.prune();
			}
		}
	}

	/**
	 * For non-composed leaf template elements there is a free choice to use a shared or template variable. Since there may be multiple
	 * candidate sites for the template variable, normalize by using a shared variable.
	 */
	private void normalizeRelation(@NonNull Relation asRelation) {
		//
		//	Find all references to all variables within the Relation
		//
		Map<@NonNull VariableDeclaration, @NonNull List<@NonNull Element>> variable2reference = new HashMap<>();
		List<OCLExpression> whenExpressions = new ArrayList<>();
		//		whenExpressions.add(asRelation.getWhen());
		for (@NonNull EObject eObject : new TreeIterable(asRelation, true)) {
			List<@NonNull VariableDeclaration> referredVariables = null;
			if (eObject instanceof VariableExp) {
				referredVariables = Lists.newArrayList(((VariableExp)eObject).getReferredVariable());
			}
			else if (eObject instanceof TemplateExp) {
				TemplateExp templateExp = (TemplateExp)eObject;
				referredVariables = Lists.newArrayList(templateExp.getBindsTo());
				if (eObject instanceof CollectionTemplateExp) {
					referredVariables.add(((CollectionTemplateExp)eObject).getRest());
				}
				OCLExpression where = templateExp.getWhere();
				if (where != null) {
					whenExpressions.add(where);
				}
			}
			else if (eObject instanceof DomainPattern) {
				referredVariables = Lists.newArrayList(((DomainPattern)eObject).getBindsTo());
			}
			if (referredVariables != null) {
				for (@NonNull VariableDeclaration referredVariable : referredVariables) {
					List<@NonNull Element> references = variable2reference.get(referredVariable);
					if (references == null) {
						references = new ArrayList<>();
						variable2reference.put(referredVariable, references);
					}
					references.add((Element)eObject);
				}
			}
		}
		//
		//	Replace leaf non-composite template variables
		//
		for (@NonNull VariableDeclaration variable : variable2reference.keySet()) {
			List<@NonNull Element> references = variable2reference.get(variable);
			assert references != null;
			if (variable instanceof TemplateVariable) {
				boolean canBeShared = true;
				for (@NonNull Element reference : references) {
					if (reference instanceof TemplateExp) {
						EObject eContainer = reference.eContainer();
						if (eContainer instanceof PropertyTemplateItem) {
							if (reference instanceof ObjectTemplateExp) {
								ObjectTemplateExp objectTemplateExp = (ObjectTemplateExp)reference;
								if (!objectTemplateExp.getPart().isEmpty()) {
									canBeShared = false;
									break;
								}
								Property asProperty = QVTrelationUtil.getReferredProperty(((PropertyTemplateItem)eContainer));
								if ((asProperty == null) || asProperty.isIsComposite()) {
									// perhaps this needs a further is there a when/where reference??
									//									canBeShared = false;
									//									break;
								}
							}
							else if (reference instanceof CollectionTemplateExp) {
								CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)reference;
								if (!collectionTemplateExp.getMember().isEmpty()) {
									canBeShared = false;
									break;
								}
								if (collectionTemplateExp.getRest() != null) {
									canBeShared = false;
									break;
								}
							}
						}
						else {
							canBeShared = false;
							break;
						}
					}
					//					EReference eContainmentFeature = reference.eContainmentFeature();
					//					EClassifier eType = eContainmentFeature.getEType();
					//					if (!eType.isInstance(PivotPackage.Literals.OCL_EXPRESSION)) {
					//						canBeShared = false;
					//						break;
					//					}
				}
				if (canBeShared) {
					VariableDeclaration sharedVariable = QVTrelationFactory.eINSTANCE.createSharedVariable();
					sharedVariable.setName(variable.getName());
					sharedVariable.setType(variable.getType());
					//					sharedVariable.setIsImplicit(variable.isIsImplicit());
					sharedVariable.setIsRequired(variable.isIsRequired());
					//					sharedVariable.setOwnedInit(variable.get);
					QVTbaseUtil.replaceChild(variable, sharedVariable);
					for (@NonNull Element reference : references) {
						if (reference instanceof VariableExp) {
							((VariableExp)reference).setReferredVariable(sharedVariable);
						}
						else if (reference instanceof ObjectTemplateExp) {
							QVTbaseUtil.replaceChild(reference, PivotUtil.createVariableExp(sharedVariable));
						}
						else if (reference instanceof CollectionTemplateExp) {
							QVTbaseUtil.replaceChild(reference, PivotUtil.createVariableExp(sharedVariable));
						}
						else if (reference instanceof DomainPattern) {
							((DomainPattern)reference).getBindsTo().remove(variable);
						}
					}
				}
			}
		}
		//
		//	Replace domain where's by relation when's
		//
		Pattern whenPattern = asRelation.getWhen();
		for (OCLExpression whenExpression : whenExpressions) {
			PivotUtilInternal.resetContainer(whenExpression);
			Predicate asPredicate = QVTbaseFactory.eINSTANCE.createPredicate();
			asPredicate.setConditionExpression(whenExpression);
			if (whenPattern == null) {
				whenPattern = QVTbaseFactory.eINSTANCE.createPattern();
				asRelation.setWhen(whenPattern);
			}
			whenPattern.getPredicate().add(asPredicate);
		}
	}


	@Override
	protected void setUp() throws Exception {
		XtextCompilerUtil.doQVTrelationSetup();
		if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
			UMLXStandaloneSetup.doSetup();
		}
		super.setUp();
	}

	public void testUMLXLoad_Forward2Reverse_qvtr() throws Exception {
		URI inputURI = getResourceURI("org.eclipse.qvtd.xtext.qvtrelation.tests/models/forward2reverse/Forward2Reverse.qvtr");
		URI pivotURI = getTestURI("Forward2Reverse.qvtras");
		URI umlxURI = getTestURI("Forward2Reverse.umlx");
		doLoadTest(inputURI, pivotURI, umlxURI);
	}

	public void testUMLXLoad_Keys_qvtr() throws Exception {
		URI inputURI = getResourceURI("org.eclipse.qvtd.xtext.qvtrelation.tests/models/misc/Keys.qvtr");
		URI pivotURI = getTestURI("Keys.qvtras");
		URI umlxURI = getTestURI("Keys.umlx");
		doLoadTest(inputURI, pivotURI, umlxURI);
	}

	public void testUMLXLoad_RelToCore_qvtr() throws Exception {
		URI inputURI = getResourceURI("org.eclipse.qvtd.examples.qvtrelation.reltocore/model/RelToCore.qvtr");
		URI pivotURI =  getTestURI("RelToCore.qvtras");
		URI umlxURI = getTestURI("RelToCore.umlx");
		doLoadTest(inputURI, pivotURI, umlxURI);
	}

	public void testUMLXLoad_SeqToStm_qvtr() throws Exception {
		URI inputURI = getResourceURI("org.eclipse.qvtd.xtext.qvtrelation.tests/models/seq2stm/SeqToStm.qvtr");
		URI pivotURI = getTestURI("SeqToStm.qvtras");
		URI umlxURI = getTestURI("SeqToStm.umlx");
		doLoadTest(inputURI, pivotURI, umlxURI);
	}

	public void testUMLXLoad_SimplerRelToCore_qvtr() throws Exception {
		URI inputURI = getResourceURI("org.eclipse.qvtd.examples.qvtrelation.reltocore/model/SimplerRelToCore.qvtr");
		URI pivotURI = getTestURI("SimplerRelToCore.qvtras");
		URI umlxURI = getTestURI("SimplerRelToCore.umlx");
		doLoadTest(inputURI, pivotURI, umlxURI);
	}

	public void testUMLXRoundtrip_Forward2Reverse_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/forward2reverse/", "Forward2Reverse", true);
	}

	public void testUMLXRoundtrip_HierarchicalStateMachine2FlatStateMachine_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/hstm2fstm/", "HierarchicalStateMachine2FlatStateMachine", true);
	}

	public void testUMLXRoundtrip_Iterated2Iterated_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/iterated2iterated/", "Iterated2Iterated", true);
	}

	public void testUMLXRoundtrip_Keys_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/misc/", "Keys", true);
	}

	public void testUMLXRoundtrip_MiToSiSimple_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/mitosi/", "MiToSiSimple", true);
	}

	public void testUMLXRoundtrip_PN2SC_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/pn2sc/", "PetriNet2StateChart", true);
	}

	public void testUMLXRoundtrip_SeqToStm_qvtr() throws Exception {
//		BaseLinkingService.DEBUG_RETRY.setState(true);
		doRoundTripTest("org.eclipse.qvtd.xtext.qvtrelation.tests/models/seq2stm/", "SeqToStm", true);
	}

	public void testUMLXRoundtrip_SimplerRelToCore_qvtr() throws Exception {
		doRoundTripTest("org.eclipse.qvtd.examples.qvtrelation.reltocore/model/", "SimplerRelToCore", true);
	}
}
