/*****************************************************************************
 * Copyright (c) 2017 CEA LIST 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:
 *   Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
 *   
 *****************************************************************************/

package org.eclipse.papyrus.interoperability.sysml14.sysml.xmi.helper;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.gmf.runtime.notation.Bendpoints;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.DecorationNode;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.IdentityAnchor;
import org.eclipse.gmf.runtime.notation.Location;
import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.gmf.runtime.notation.StringValueStyle;
import org.eclipse.gmf.runtime.notation.Style;
import org.eclipse.papyrus.infra.viewpoints.style.PapyrusViewStyle;

/**
 * This class defines the needed methods to preserve or create the Notation XMI identifiers.
 */
public class NotationXMIIDHelper {

	/**
	 * The diagram compatibility version identifier.
	 */
	private static final String DIAGRAM_COMPATIBILITY_VERSION = "diagram_compatibility_version"; //$NON-NLS-1$

	/**
	 * The Bendpoints identifier.
	 */
	private static final String BENDPOINTS = "bendpoints"; //$NON-NLS-1$

	/**
	 * The Bounds identifier.
	 */
	private static final String BOUNDS = "bounds"; //$NON-NLS-1$

	/**
	 * The Connector identifier.
	 */
	private static final String CONNECTOR = "connector"; //$NON-NLS-1$

	/**
	 * The IdentityAnchor identifier.
	 */
	private static final String IDENTITY_ANCHOR = "identityAnchor"; //$NON-NLS-1$

	/**
	 * The Location identifier.
	 */
	private static final String LOCATION = "location"; //$NON-NLS-1$

	/**
	 * The PapyrusViewStyle identifier.
	 */
	private static final String PAPYRUS_VIEW_STYLE = "papyrusViewStyle"; //$NON-NLS-1$

	/**
	 * The Shape identifier.
	 */
	private static final String SHAPE = "shape"; //$NON-NLS-1$

	/**
	 * The 'from' separator in identifier.
	 */
	private static final String FROM = "_from_"; //$NON-NLS-1$

	/**
	 * The 'Of' separator in identifier.
	 */
	private static final String OF = "_Of_"; //$NON-NLS-1$

	/**
	 * The 'to' separator in identifier.
	 */
	private static final String TO = "_to_"; //$NON-NLS-1$

	/**
	 * The underscore separator.
	 */
	private static final String UNDERSCORE = "_"; //$NON-NLS-1$

	/**
	 * This allows to calculate the identifiers of created Notation elements.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param current
	 *            The object to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateNeededId(final XMIResource res, final Object current, final Map<EObject, String> oldIds) {
		if (current instanceof DecorationNode) {
			calculateDecorationNode(res, (DecorationNode) current, oldIds);
		} else if (current instanceof Diagram) {
			calculateDiagram(res, (Diagram) current, oldIds);
		} else if (current instanceof Style) {
			calculateStyle(res, (Style) current, oldIds);
		} else if (current instanceof Bounds) {
			calculateBounds(res, (Bounds) current, oldIds);
		} else if (current instanceof Location) {
			calculateLocation(res, (Location) current, oldIds);
		} else if (current instanceof EAnnotation) {
			calculateEAnnotation(res, (EAnnotation) current, oldIds);
		} else if (current instanceof Bendpoints) {
			calculateBendpoints(res, (Bendpoints) current, oldIds);
		} else if (current instanceof IdentityAnchor) {
			calculateIdentityAnchor(res, (IdentityAnchor) current, oldIds);
		}
	}

	/**
	 * This allows to calculate the identifiers of created DecorationNode.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param decorationNode
	 *            The DecorationNode to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateDecorationNode(final XMIResource res, final DecorationNode decorationNode, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(decorationNode)) {
			final String containerID = ((XMIResource) decorationNode.eContainer().eResource()).getID(decorationNode.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(decorationNode.getType());
			stringBuilder.append(OF);
			stringBuilder.append(containerID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(decorationNode, stringBuilder.toString());
			oldIds.put(decorationNode, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of converted Diagram.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param diagram
	 *            The Diagram to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateDiagram(final XMIResource res, final Diagram diagram, final Map<EObject, String> oldIds) {
		StringValueStyle compatibilityVersion = null;
		Set<PapyrusViewStyle> papyrusViewStyles = new HashSet<PapyrusViewStyle>();

		@SuppressWarnings("unchecked")
		final Iterator<EObject> styles = diagram.getStyles().iterator();
		while (styles.hasNext()) {
			final EObject style = styles.next();
			if (style instanceof PapyrusViewStyle) {
				papyrusViewStyles.add((PapyrusViewStyle) style);
			} else if (style instanceof StringValueStyle && ((StringValueStyle) style).getName().equals("diagram_compatibility_version")) {
				compatibilityVersion = (StringValueStyle) style;
			}
		}
		final String diagramID = ((XMIResource) diagram.eResource()).getID(diagram);

		if (null != compatibilityVersion && !oldIds.containsKey(compatibilityVersion)) {
			final StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DIAGRAM_COMPATIBILITY_VERSION);
			stringBuilder.append(OF);
			stringBuilder.append(diagramID);
			res.setID(compatibilityVersion, stringBuilder.toString());
			oldIds.put(compatibilityVersion, stringBuilder.toString());
		}

		for (final PapyrusViewStyle papyrusViewStyle : papyrusViewStyles) {
			if (!oldIds.containsKey(papyrusViewStyle)) {
				final StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.append(PAPYRUS_VIEW_STYLE);
				stringBuilder.append(((XMIResource) papyrusViewStyle.getOwner().eResource()).getID(papyrusViewStyle.getOwner()));
				stringBuilder.append(OF);
				stringBuilder.append(diagramID);
				res.setID(papyrusViewStyle, stringBuilder.toString());
				oldIds.put(papyrusViewStyle, stringBuilder.toString());
			}
		}
	}

	/**
	 * This allows to calculate the identifiers of created Style.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param style
	 *            The Style to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateStyle(final XMIResource res, final Style style, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(style)) {
			final String containerID = ((XMIResource) style.eContainer().eResource()).getID(style.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(style.eClass().getName());
			stringBuilder.append(OF);
			stringBuilder.append(containerID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(style, stringBuilder.toString());
			oldIds.put(style, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created Bounds.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param bounds
	 *            The Bounds to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateBounds(final XMIResource res, final Bounds bounds, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(bounds)) {
			final String containerID = ((XMIResource) bounds.eContainer().eResource()).getID(bounds.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(BOUNDS);
			stringBuilder.append(OF);
			stringBuilder.append(containerID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(bounds, stringBuilder.toString());
			oldIds.put(bounds, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created Location.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param location
	 *            The Location to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateLocation(final XMIResource res, final Location location, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(location)) {
			final String containerID = ((XMIResource) location.eContainer().eResource()).getID(location.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(LOCATION);
			stringBuilder.append(OF);
			stringBuilder.append(containerID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(location, stringBuilder.toString());
			oldIds.put(location, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created EAnnotation and details.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param eAnnotation
	 *            The EAnnotation to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateEAnnotation(final XMIResource res, final EAnnotation eAnnotation, final Map<EObject, String> oldIds) {
		final String containerID = ((XMIResource) eAnnotation.eContainer().eResource()).getID(eAnnotation.eContainer());

		String eAnnotationID = null;
		if (!oldIds.containsKey(eAnnotation)) {
			final StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(eAnnotation.getSource());
			stringBuilder.append(OF);
			stringBuilder.append(containerID);
			eAnnotationID = stringBuilder.toString();
			res.setID(eAnnotation, eAnnotationID);
			oldIds.put(eAnnotation, eAnnotationID);
		} else {
			eAnnotationID = oldIds.get(eAnnotation);
		}

		for (final Entry<String, String> detail : eAnnotation.getDetails()) {
			if (!oldIds.containsKey(detail) && detail instanceof EStringToStringMapEntryImpl) {
				final StringBuilder eAnnotationStringBuilder = new StringBuilder();
				eAnnotationStringBuilder.append(detail.getKey());
				eAnnotationStringBuilder.append(OF);
				eAnnotationStringBuilder.append(eAnnotationID);
				res.setID((EStringToStringMapEntryImpl) detail, eAnnotationStringBuilder.toString());
				oldIds.put((EStringToStringMapEntryImpl) detail, eAnnotationStringBuilder.toString());
			}
		}
	}

	/**
	 * This allows to calculate the identifiers of created Shape.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param shape
	 *            The Shape to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateShape(final XMIResource res, final Shape shape, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(shape)) {
			final String elementID = ((XMIResource) shape.getElement().eResource()).getID(shape.getElement());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(SHAPE);
			stringBuilder.append(OF);
			stringBuilder.append(elementID);

			// Manage the existing shape id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(shape, stringBuilder.toString());
			oldIds.put(shape, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created Connector.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param connector
	 *            The Connector to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateConnector(final XMIResource res, final Connector connector, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(connector)) {
			final String sourceID = ((XMIResource) connector.getSource().eResource()).getID(connector.getSource());
			final String targetID = ((XMIResource) connector.getTarget().eResource()).getID(connector.getTarget());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(CONNECTOR);
			stringBuilder.append(FROM);
			stringBuilder.append(sourceID);
			stringBuilder.append(TO);
			stringBuilder.append(targetID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(connector, stringBuilder.toString());
			oldIds.put(connector, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created Bendpoints.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param bendpoints
	 *            The Bendpoints to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateBendpoints(final XMIResource res, final Bendpoints bendpoints, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(bendpoints)) {
			final String elementID = ((XMIResource) bendpoints.eContainer().eResource()).getID(bendpoints.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(BENDPOINTS);
			stringBuilder.append(OF);
			stringBuilder.append(elementID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(bendpoints, stringBuilder.toString());
			oldIds.put(bendpoints, stringBuilder.toString());
		}
	}

	/**
	 * This allows to calculate the identifiers of created IdentityAnchor.
	 * 
	 * @param res
	 *            The Notation Resource.
	 * @param identityAnchor
	 *            The IdentityAnchor to manage its identifier.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 */
	public static void calculateIdentityAnchor(final XMIResource res, final IdentityAnchor identityAnchor, final Map<EObject, String> oldIds) {
		if (!oldIds.containsKey(identityAnchor)) {
			final String elementID = ((XMIResource) identityAnchor.eContainer().eResource()).getID(identityAnchor.eContainer());

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(IDENTITY_ANCHOR);
			stringBuilder.append(OF);
			stringBuilder.append(elementID);

			// Manage the existing connector id with incremental suffix item if needed
			stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);

			res.setID(identityAnchor, stringBuilder.toString());
			oldIds.put(identityAnchor, stringBuilder.toString());
		}
	}

	/**
	 * This allows to suffix the initial string builder if the id already exist.
	 * 
	 * @param initialString
	 *            The initial string builder.
	 * @param oldIds
	 *            The existing objects and their identifiers.
	 * @return The string builder incremented if needed.
	 */
	protected static StringBuilder incrementStringBuilder(final String initialString, final Map<EObject, String> oldIds) {
		StringBuilder subStringBuilder = new StringBuilder(initialString);

		boolean idAlreadyExist = oldIds.containsValue(initialString);
		int incremental = 2;
		while (idAlreadyExist) {
			subStringBuilder = new StringBuilder(initialString);
			subStringBuilder.append(UNDERSCORE);
			subStringBuilder.append(incremental);
			if (!oldIds.containsValue(subStringBuilder.toString())) {
				idAlreadyExist = false;
			}
			incremental++;
		}

		return subStringBuilder;
	}
}
