/*******************************************************************************
 * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *   Contributors:
 *      Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.capra.handler.uml;

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

import org.eclipse.capra.core.adapters.Connection;
import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Message;
import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Relationship;
import org.eclipse.uml2.uml.Transition;

/**
 * Handler to allow tracing to and from arbitrary UML model elements.
 * 
 * @author Dominik Einkemmer
 */
public class UMLHandler extends AbstractArtifactHandler<EModelElement> {

	@Override
	public EObject createWrapper(EModelElement artifact, EObject artifactModel) {
		return artifact;
	}

	@Override
	public EModelElement resolveWrapper(EObject wrapper) {
		return (EModelElement) wrapper;
	}

	@Override
	public String getDisplayName(EModelElement artifact) {
		return artifact.eClass().getName();
	}

	@Override
	public List<Connection> addInternalLinks(EObject investigatedElement, List<String> selectedRelationshipTypes) {
		List<Integer> duplicationCheck = new ArrayList<>();
		List<Connection> allElements = new ArrayList<>();
		if (Relationship.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				Relationship rel = Relationship.class.cast(investigatedElement);
				List<EObject> relatedElements = new ArrayList<>();
				int connectionHash = investigatedElement.hashCode() + rel.hashCode();
				for (Element element : rel.getRelatedElements()) {
					relatedElements.add(element);
					connectionHash += element.hashCode();
				}
				if (!duplicationCheck.contains(connectionHash)) {
					Connection conn = new Connection(investigatedElement, relatedElements, rel);
					allElements.add(conn);
					duplicationCheck.add(connectionHash);
				}
			}
		} else if (ActivityEdge.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				ActivityEdge activityEdge = ActivityEdge.class.cast(investigatedElement);
				List<EObject> relatedElements = new ArrayList<>();
				relatedElements.add(activityEdge.getTarget());
				relatedElements.add(activityEdge.getSource());
				int connectionHash = investigatedElement.hashCode() + activityEdge.hashCode();
				if (!duplicationCheck.contains(connectionHash)) {
					Connection conn = new Connection(investigatedElement, relatedElements, activityEdge);
					allElements.add(conn);
					duplicationCheck.add(connectionHash);
				}
			}
		} else if (Transition.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				Transition transition = Transition.class.cast(investigatedElement);
				List<EObject> relatedElements = new ArrayList<>();
				relatedElements.add(transition.getSource());
				relatedElements.add(transition.getTarget());
				int connectionHash = investigatedElement.hashCode() + transition.hashCode()
						+ transition.getTarget().hashCode() + transition.getSource().hashCode();
				if (!duplicationCheck.contains(connectionHash)) {
					Connection conn = new Connection(investigatedElement, relatedElements, transition);
					allElements.add(conn);
					duplicationCheck.add(connectionHash);
				}
			}
		} else if (Message.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				Message msg = Message.class.cast(investigatedElement);
				MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent();
				MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent();
				List<EObject> relatedElements = new ArrayList<>();
				relatedElements.add(sender.getCovered());
				relatedElements.add(receiver.getCovered());
				if (receiver != null) {
					int connectionHash = investigatedElement.hashCode() + msg.hashCode()
							+ msg.getMessageSort().hashCode() + sender.getCovered().hashCode()
							+ receiver.getCovered().hashCode();
					if (!duplicationCheck.contains(connectionHash)) {
						Connection conn = new Connection(investigatedElement, relatedElements, msg);
						allElements.add(conn);
						duplicationCheck.add(connectionHash);
					}
				}
			}
		} else if (Port.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				Port port = Port.class.cast(investigatedElement);
				EList<Interface> provideds = port.getProvideds();
				EList<Interface> requireds = port.getRequireds();
				List<EObject> relatedElements = new ArrayList<>();
				relatedElements.addAll(requireds);
				relatedElements.addAll(provideds);
				int connectionHash = investigatedElement.hashCode() + port.hashCode();
				for (EObject el : relatedElements) {
					connectionHash += el.hashCode();
				}
				if (!duplicationCheck.contains(connectionHash)) {
					Connection conn = new Connection(investigatedElement, relatedElements, port);
					allElements.add(conn);
					duplicationCheck.add(connectionHash);
				}
			}
		} else if (Connector.class.isAssignableFrom(investigatedElement.getClass())) {
			if (selectedRelationshipTypes.size() == 0
					|| selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) {
				Connector connector = Connector.class.cast(investigatedElement);
				EList<ConnectorEnd> connectedEnds = connector.getEnds();
				List<EObject> relatedElements = new ArrayList<>();
				connectedEnds.forEach(connectedEnd -> {
					if (connectedEnd.getPartWithPort() != null) {
						relatedElements.add(connectedEnd.getPartWithPort());
					} else {
						relatedElements.add(connectedEnd);
					}
				});
				int connectionHash = investigatedElement.hashCode() + connector.hashCode();
				for (EObject el : relatedElements) {
					connectionHash += el.hashCode();
				}
				if (!duplicationCheck.contains(connectionHash)) {
					Connection conn = new Connection(investigatedElement, relatedElements, connector);
					allElements.add(conn);
					duplicationCheck.add(connectionHash);
				}
			}
		} else {
			EObject root = EcoreUtil.getRootContainer(investigatedElement);
			TreeIterator<EObject> modelContents = root.eAllContents();
			while (modelContents.hasNext()) {
				EObject content = modelContents.next();
				if (selectedRelationshipTypes.size() == 0
						|| selectedRelationshipTypes.contains(content.eClass().getName())) {
					if (Relationship.class.isAssignableFrom(content.getClass())) {
						Relationship relation = Relationship.class.cast(content);
						boolean isRelatedToElement = false;
						List<EObject> relatedElements = new ArrayList<>();
						for (Element relatedElement : relation.getRelatedElements()) {
							if (relatedElement.hashCode() == investigatedElement.hashCode()) {
								isRelatedToElement = true;
							} else {
								relatedElements.add(relatedElement);
							}
						}
						if (isRelatedToElement) {
							int connectionHash = investigatedElement.hashCode() + relation.hashCode();
							for (EObject element : relatedElements) {
								connectionHash += element.hashCode();
							}
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, relation);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						}
					} else if (ActivityEdge.class.isAssignableFrom(content.getClass())) {
						if (selectedRelationshipTypes.size() == 0
								|| selectedRelationshipTypes.contains(content.eClass().getName())) {
							ActivityEdge activityEdge = ActivityEdge.class.cast(content);
							List<EObject> relatedElements = new ArrayList<>();
							if (activityEdge.getTarget().hashCode() == investigatedElement.hashCode()) {
								relatedElements.add(activityEdge.getSource());
							} else if (activityEdge.getSource().hashCode() == investigatedElement.hashCode()) {
								relatedElements.add(activityEdge.getTarget());
							}
							int connectionHash = investigatedElement.hashCode() + activityEdge.hashCode();
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, activityEdge);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						}
					} else if (Transition.class.isAssignableFrom(content.getClass())) {
						Transition transition = Transition.class.cast(content);
						List<EObject> relatedElements = new ArrayList<>();
						if (transition.getSource().hashCode() == investigatedElement.hashCode()) {
							relatedElements.add(transition.getTarget());
							int connectionHash = investigatedElement.hashCode() + transition.hashCode()
									+ transition.getTarget().hashCode();
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, transition);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						} else if (transition.getTarget().hashCode() == investigatedElement.hashCode()) {
							relatedElements.add(transition.getSource());
							int connectionHash = investigatedElement.hashCode() + transition.hashCode()
									+ transition.getSource().hashCode();
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, transition);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						}
					} else if (Message.class.isAssignableFrom(content.getClass())) {
						Message msg = Message.class.cast(content);
						MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg
								.getReceiveEvent();
						MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent();
						List<EObject> relatedElements = new ArrayList<>();
						if (receiver != null && receiver.getCovered() != null) {
							if (receiver.getCovered().hashCode() == investigatedElement.hashCode()) {
								relatedElements.add(sender.getCovered());
								int connectionHash = investigatedElement.hashCode() + msg.hashCode()
										+ msg.getMessageSort().hashCode() + sender.getCovered().hashCode();
								if (!duplicationCheck.contains(connectionHash)) {
									Connection conn = new Connection(investigatedElement, relatedElements, msg);
									allElements.add(conn);
									duplicationCheck.add(connectionHash);
								}
							} else if (sender.getCovered().hashCode() == investigatedElement.hashCode()) {
								relatedElements.add(receiver.getCovered());
								int connectionHash = investigatedElement.hashCode() + msg.hashCode()
										+ msg.getMessageSort().hashCode() + receiver.getCovered().hashCode();
								if (!duplicationCheck.contains(connectionHash)) {
									Connection conn = new Connection(investigatedElement, relatedElements, msg);
									allElements.add(conn);
									duplicationCheck.add(connectionHash);
								}
							}
						}
					} else if (Port.class.isAssignableFrom(content.getClass())) {
						Port port = Port.class.cast(content);
						EList<Interface> provideds = port.getProvideds();
						boolean investigatedIsProvided = false;
						for (Interface provided : provideds) {
							if (provided.hashCode() == investigatedElement.hashCode()) {
								investigatedIsProvided = true;
							}
						}
						EList<Interface> requireds = port.getRequireds();
						boolean investigatedIsRequired = false;
						for (Interface required : requireds) {
							if (required.hashCode() == investigatedElement.hashCode()) {
								investigatedIsRequired = true;
							}

						}
						List<EObject> relatedElements = new ArrayList<>();

						if (investigatedIsProvided) {
							relatedElements.addAll(requireds);
						} else if (investigatedIsRequired) {
							relatedElements.addAll(provideds);
						}
						if (investigatedIsProvided || investigatedIsRequired) {
							int connectionHash = investigatedElement.hashCode() + port.hashCode();
							for (EObject el : relatedElements) {
								connectionHash += el.hashCode();
							}
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, port);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						}
					} else if (Connector.class.isAssignableFrom(content.getClass())) {
						Connector connector = Connector.class.cast(content);
						EList<ConnectorEnd> connectedEnds = connector.getEnds();
						List<EObject> relatedElements = new ArrayList<>();
						boolean isConnected = false;
						for (ConnectorEnd connectedEnd : connectedEnds) {
							if (connectedEnd.getPartWithPort() != null) {
								relatedElements.add(connectedEnd.getPartWithPort());
								if (connectedEnd.getPartWithPort().hashCode() == investigatedElement.hashCode()) {
									isConnected = true;
									relatedElements.remove(connectedEnd.getPartWithPort());
								}
							} else {
								relatedElements.add(connectedEnd);
								if (connectedEnd.hashCode() == investigatedElement.hashCode()) {
									isConnected = true;
									relatedElements.remove(connectedEnd);
								}
							}
						}
						if (isConnected) {
							int connectionHash = investigatedElement.hashCode() + connector.hashCode();
							for (EObject el : relatedElements) {
								connectionHash += el.hashCode();
							}
							if (!duplicationCheck.contains(connectionHash)) {
								Connection conn = new Connection(investigatedElement, relatedElements, connector);
								allElements.add(conn);
								duplicationCheck.add(connectionHash);
							}
						}
					}
				}
			}
		}
		return allElements;
	}

	@Override
	public boolean isThereAnInternalTraceBetween(EObject first, EObject second) {
		if (first.equals(second)) {
			return false;
		}
		if (Relationship.class.isAssignableFrom(first.getClass())
				|| Relationship.class.isAssignableFrom(second.getClass())) {
			Relationship rel;
			if (Relationship.class.isAssignableFrom(first.getClass())) {
				rel = Relationship.class.cast(first);
			} else {
				rel = Relationship.class.cast(second);
			}
			boolean isRelated = false;
			for (Element relatedElement : rel.getRelatedElements()) {
				if (relatedElement.hashCode() == first.hashCode() || relatedElement.hashCode() == second.hashCode()) {
					isRelated = true;
				}
			}

			return isRelated;

		} else if (ActivityEdge.class.isAssignableFrom(first.getClass())
				|| ActivityEdge.class.isAssignableFrom(second.getClass())) {
			ActivityEdge activityEdge;
			if (ActivityEdge.class.isAssignableFrom(first.getClass())) {
				activityEdge = ActivityEdge.class.cast(first);
			} else {
				activityEdge = ActivityEdge.class.cast(second);
			}
			int sourceHash = activityEdge.getSource().hashCode();
			int targetHash = activityEdge.getTarget().hashCode();

			boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
			boolean relationContainsSecondElement = sourceHash == second.hashCode() || sourceHash == second.hashCode();
			if (relationContainsFirstElement && relationContainsSecondElement) {
				return true;
			}
		} else if (Transition.class.isAssignableFrom(first.getClass())
				|| Transition.class.isAssignableFrom(second.getClass())) {
			Transition transition;
			if (Transition.class.isAssignableFrom(first.getClass())) {
				transition = Transition.class.cast(first);
			} else {
				transition = Transition.class.cast(second);
			}
			int sourceHash = transition.getSource().hashCode();
			int targetHash = transition.getTarget().hashCode();
			boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
			boolean relationContainsSecondElement = sourceHash == second.hashCode() || sourceHash == second.hashCode();
			if (relationContainsFirstElement && relationContainsSecondElement) {
				return true;
			}
		} else if (Message.class.isAssignableFrom(first.getClass())
				|| Message.class.isAssignableFrom(second.getClass())) {
			Message msg;
			if (Message.class.isAssignableFrom(first.getClass())) {
				msg = Message.class.cast(first);
			} else {
				msg = Message.class.cast(second);
			}
			MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent();
			MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent();
			if (receiver != null) {
				int sourceHash = sender.getCovered().hashCode();
				int targetHash = receiver.getCovered().hashCode();
				boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
				boolean relationContainsSecondElement = sourceHash == second.hashCode()
						|| targetHash == second.hashCode();
				if (relationContainsFirstElement && relationContainsSecondElement) {
					return true;
				}
			}
		} else if (Connector.class.isAssignableFrom(first.getClass())
				|| Connector.class.isAssignableFrom(second.getClass())) {
			Connector connector;
			if (Connector.class.isAssignableFrom(first.getClass())) {
				connector = Connector.class.cast(first);
			} else {
				connector = Connector.class.cast(second);
			}
			EList<ConnectorEnd> connectedEnds = connector.getEnds();
			boolean isRelated = false;
			for (ConnectorEnd connectedEnd : connectedEnds) {
				if (connectedEnd.getPartWithPort() != null
						&& (connectedEnd.getPartWithPort().hashCode() == first.hashCode()
								|| connectedEnd.getPartWithPort().hashCode() == second.hashCode())) {
					isRelated = true;
				} else if (connectedEnd.hashCode() == first.hashCode()
						|| connectedEnd.hashCode() == second.hashCode()) {
					isRelated = true;
				}
			}
			if (isRelated) {
				return true;
			}
		} else {
			boolean relationContainsFirstElement = false;
			boolean relationContainsSecondElement = false;
			int numberofInternalLinks = 0;
			EObject root = EcoreUtil.getRootContainer(first);
			TreeIterator<EObject> modelContents = root.eAllContents();
			while (modelContents.hasNext()) {
				EObject content = modelContents.next();
				if (Relationship.class.isAssignableFrom(content.getClass())) {
					Relationship relation = Relationship.class.cast(content);
					for (Element relatedElement : relation.getRelatedElements()) {
						if (relatedElement.hashCode() == first.hashCode()) {
							relationContainsFirstElement = true;
						} else if (relatedElement.hashCode() == second.hashCode()) {
							relationContainsSecondElement = true;
						}
					}
					if (relationContainsFirstElement && relationContainsSecondElement) {
						numberofInternalLinks++;
					}
				} else if (ActivityEdge.class.isAssignableFrom(content.getClass())) {
					ActivityEdge activityEdge = ActivityEdge.class.cast(content);
					int sourceHash = activityEdge.getSource().hashCode();
					int targetHash = activityEdge.getTarget().hashCode();

					relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
					relationContainsSecondElement = sourceHash == second.hashCode() || targetHash == second.hashCode();
					if (relationContainsFirstElement && relationContainsSecondElement) {
						numberofInternalLinks++;
					}
				} else if (Transition.class.isAssignableFrom(content.getClass())) {
					Transition transition = Transition.class.cast(content);
					int sourceHash = transition.getSource().hashCode();
					int targetHash = transition.getTarget().hashCode();
					relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
					relationContainsSecondElement = sourceHash == second.hashCode() || targetHash == second.hashCode();
					if (relationContainsFirstElement && relationContainsSecondElement) {
						numberofInternalLinks++;
					}
				} else if (Message.class.isAssignableFrom(content.getClass())) {
					Message msg = Message.class.cast(content);
					MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent();
					MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent();
					if (receiver != null) {
						int sourceHash = sender.getCovered().hashCode();
						int targetHash = receiver.getCovered().hashCode();
						relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode();
						relationContainsSecondElement = sourceHash == second.hashCode()
								|| targetHash == second.hashCode();
						if (relationContainsFirstElement && relationContainsSecondElement) {
							numberofInternalLinks++;
						}
					} else if (Connector.class.isAssignableFrom(content.getClass())) {
						Connector connector = Connector.class.cast(content);
						EList<ConnectorEnd> connectedEnds = connector.getEnds();
						for (ConnectorEnd connectedEnd : connectedEnds) {
							if (connectedEnd.getPartWithPort() != null
									&& (connectedEnd.getPartWithPort().hashCode() == first.hashCode()
											|| connectedEnd.getPartWithPort().hashCode() == second.hashCode())) {
								relationContainsFirstElement = true;
							} else if (connectedEnd.hashCode() == first.hashCode()
									|| connectedEnd.hashCode() == second.hashCode()) {
								relationContainsSecondElement = true;
							}
						}
						if (relationContainsFirstElement && relationContainsSecondElement) {
							numberofInternalLinks++;
						}
					}
				}
			}
			if (numberofInternalLinks > 0) {
				return true;
			}
		}
		return false;

	}

	@Override
	public String generateMarkerMessage(IResourceDelta delta, String wrapperUri) {
		return null;
	}
}
