/**
 * Copyright (c) 2015, 2018 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.xtext.qvtcore.tests;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
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.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.examples.xtext.tests.XtextTestCase.Normalizer;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.qvtd.xtext.qvtbase.tests.ModelNormalizer;
import org.eclipse.qvtd.xtext.qvtcore.tests.upper2lower.simplegraph.SimplegraphPackage;

/**
 * Upper2LowerNormalizer normalises the results of the UpperToLower transformation.
 *
 * Even though everything is ordered in the input/output model, the edges/incoming/outgoing lists cn be independently ordered, and only
 * the edges order is preserved in the middle model.
 */
public class Upper2LowerNormalizer implements ModelNormalizer
{
	public static final @NonNull Upper2LowerNormalizer INSTANCE = new Upper2LowerNormalizer();

	protected static class ElementComparator implements Comparator<EObject>
	{
		private final @NonNull EClass edgeClass;
		private final @NonNull EReference edgeSource;
		private final @NonNull EReference edgeTarget;
		private final @NonNull EAttribute nodeLabel;

		public ElementComparator(@NonNull EClass edgeClass, @NonNull EReference edgeSource, @NonNull EReference edgeTarget, @NonNull EAttribute nodeLabel) {
			this.edgeClass = edgeClass;
			this.edgeSource = edgeSource;
			this.edgeTarget = edgeTarget;
			this.nodeLabel = nodeLabel;
		}

		@Override
		public int compare(EObject o1, EObject o2) {
			String n1;
			String n2;
			if (edgeClass.isInstance(o1)) {
				if (!edgeClass.isInstance(o2)) {
					return 1;
				}
				n1 = (String) ((EObject)o1.eGet(edgeSource)).eGet(nodeLabel);
				n2 = (String) ((EObject)o2.eGet(edgeSource)).eGet(nodeLabel);
				if (ClassUtil.safeEquals(n1, n2)) {
					n1 = (String) ((EObject)o1.eGet(edgeTarget)).eGet(nodeLabel);
					n2 = (String) ((EObject)o2.eGet(edgeTarget)).eGet(nodeLabel);
				}
			}
			else {
				if (edgeClass.isInstance(o2)) {
					return -1;
				}
				n1 = (String) o1.eGet(nodeLabel);
				n2 = (String) o2.eGet(nodeLabel);
			}
			return ClassUtil.safeCompareTo(n1, n2);
		}
	}

	protected class GraphNormalizer implements Normalizer
	{
		protected final @NonNull EObject graph;
		protected final @NonNull EReference graphElements;
		protected final @NonNull ElementComparator elementComparator;

		public GraphNormalizer(@NonNull EObject graph, @NonNull EReference graphElements, @NonNull ElementComparator elementComparator) {
			this.graph = graph;
			this.graphElements = graphElements;
			this.elementComparator = elementComparator;
		}

		@Override
		public void denormalize() {
			throw new UnsupportedOperationException();
		}

		@Override
		public void normalize() {
			@SuppressWarnings("unchecked")
			EList<EObject> elements = (EList<EObject>) graph.eGet(graphElements);
			ECollections.sort(elements, elementComparator);
		}
	}

	protected class NodeNormalizer implements Normalizer
	{
		protected final @NonNull EObject node;
		protected final @NonNull EReference incoming;
		protected final @NonNull EReference outgoing;
		protected final @NonNull ElementComparator elementComparator;

		public NodeNormalizer(@NonNull EObject node, @NonNull EReference incoming, @NonNull EReference outgoing, @NonNull ElementComparator elementComparator) {
			this.node = node;
			this.incoming = incoming;
			this.outgoing = outgoing;
			this.elementComparator = elementComparator;
		}

		@Override
		public void denormalize() {
			throw new UnsupportedOperationException();
		}

		@Override
		public void normalize() {
			@SuppressWarnings("unchecked")EList<EObject> incomingEdges = (EList<EObject>) node.eGet(incoming);
			ECollections.sort(incomingEdges, elementComparator);
			@SuppressWarnings("unchecked")EList<EObject> outgoingEdges = (EList<EObject>) node.eGet(outgoing);
			ECollections.sort(outgoingEdges, elementComparator);
		}
	}

	@Override
	public @NonNull List<@NonNull Normalizer> normalize(@NonNull Resource resource) {
		EObject eRoot = resource.getContents().get(0);
		EPackage ePackage = eRoot.eClass().getEPackage();
		EClass graphClass = (EClass) ePackage.getEClassifier(SimplegraphPackage.Literals.GRAPH.getName());
		assert graphClass != null;
		EClass elementClass = (EClass) ePackage.getEClassifier(SimplegraphPackage.Literals.ELEMENT.getName());
		assert elementClass != null;
		EClass edgeClass = (EClass) ePackage.getEClassifier(SimplegraphPackage.Literals.EDGE.getName());
		assert edgeClass != null;
		EClass nodeClass = (EClass) ePackage.getEClassifier(SimplegraphPackage.Literals.NODE.getName());
		assert nodeClass != null;
		EReference graphElements = (EReference) graphClass.getEStructuralFeature(SimplegraphPackage.Literals.GRAPH__ELEMENT.getName());
		assert graphElements != null;
		EAttribute nodeLabel = (EAttribute) nodeClass.getEStructuralFeature(SimplegraphPackage.Literals.NODE__LABEL.getName());
		assert nodeLabel != null;
		EReference nodeIncoming = (EReference) nodeClass.getEStructuralFeature(SimplegraphPackage.Literals.NODE__INCOMING.getName());
		assert nodeIncoming != null;
		EReference nodeOutgoing = (EReference) nodeClass.getEStructuralFeature(SimplegraphPackage.Literals.NODE__OUTGOING.getName());
		assert nodeOutgoing != null;
		EReference edgeSource = (EReference) edgeClass.getEStructuralFeature(SimplegraphPackage.Literals.EDGE__SOURCE.getName());
		assert edgeSource != null;
		EReference edgeTarget = (EReference) edgeClass.getEStructuralFeature(SimplegraphPackage.Literals.EDGE__TARGET.getName());
		assert edgeTarget != null;
		ElementComparator elementComparator = new ElementComparator(edgeClass, edgeSource, edgeTarget, nodeLabel);
		List<@NonNull Normalizer> normalizers = new ArrayList<>();
		for (TreeIterator<EObject> tit = resource.getAllContents(); tit.hasNext(); ) {
			EObject eObject = tit.next();
			EClass eClass = eObject.eClass();
			if (graphClass.isSuperTypeOf(eClass)) {
				normalizers.add(new GraphNormalizer(eObject, graphElements, elementComparator));
			}
			if (nodeClass.isSuperTypeOf(eClass)) {
				normalizers.add(new NodeNormalizer(eObject, nodeIncoming, nodeOutgoing, elementComparator));
			}
		}
		for (Normalizer normalizer : normalizers) {
			normalizer.normalize();
		}
		return normalizers;
	}
}