/*******************************************************************************
 * Copyright (c) 2013 THALES GLOBAL SERVICES 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/

package org.eclipse.emf.ecoretools.design.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
import org.eclipse.emf.ecore.presentation.EcoreEditorPlugin;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.DNodeList;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.DiagramPackage;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.ext.emf.AllContents;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

import com.google.common.base.Ascii;
import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;

/**
 * Generic Ecore services usable from a VSM.
 */
public class DesignServices extends EReferenceServices {
	private static final String CLASS_DIAGRAM_CLASS_MAPPINGID = "EC EClass";

	/**
	 * Returns all the root objects of all the resources in the same
	 * resource-set as the specified object.
	 * 
	 * @param any
	 *            an EObject.
	 * @return all the root objects in the same resource-set as <code>any</code>
	 *         or an empty collection if <code>any</code> is not inside a
	 *         resource-set.
	 */
	public Collection<EObject> allRoots(EObject any) {
		Resource res = any.eResource();
		if (res != null && res.getResourceSet() != null) {
			Collection<EObject> roots = new ArrayList<EObject>();
			for (Resource childRes : res.getResourceSet().getResources()) {
				roots.addAll(childRes.getContents());
			}
			return roots;
		} else {
			return Collections.emptySet();
		}
	}

	public Collection<EPackage> rootEPackages(EObject any) {
		return Sets.newLinkedHashSet(Iterables.filter(allRoots(any),
				EPackage.class));
	}

	public Boolean isEOperation(EObject any) {
		return any instanceof EOperation;
	}

	public Boolean isEStructuralFeature(EObject any) {
		return any instanceof EStructuralFeature;
	}

	public Boolean isEPackage(EObject any) {
		return any instanceof EPackage;
	}

	public Boolean isEClass(EObject any) {
		return any instanceof EClass;
	}

	public Boolean isEEnum(EObject any) {
		return any instanceof EEnum;
	}

	protected static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel";

	protected static final String ECORE_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/Ecore";

	public EObject markForAutosize(EObject any) {
		if (any != null) {
			any.eAdapters().add(AutosizeTrigger.AUTO_SIZE_MARKER);
		}
		return any;
	}

	public EObject eContainerEContainer(EObject any) {
		if (any.eContainer() != null)
			return any.eContainer().eContainer();
		return null;
	}

	public Collection<EStringToStringMapEntryImpl> getVisibleDocAnnotations(
			EObject self, DSemanticDiagram diag) {
		// [diagram.getDisplayedEModelElements().oclAsType(ecore::EModelElement).eAnnotations.details->select(key
		// = 'documentation')/]
		Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
		for (EModelElement displayed : getDisplayedEModelElements(diag)) {
			if (!(displayed instanceof EAttribute)
					&& !(displayed instanceof EEnumLiteral)
					&& !(displayed instanceof EOperation)) {
				EAnnotation eAnnot = displayed
						.getEAnnotation(GEN_MODEL_PACKAGE_NS_URI);
				if (eAnnot != null) {
					for (EStringToStringMapEntryImpl mapEntry : Iterables
							.filter(eAnnot.getDetails(),
									EStringToStringMapEntryImpl.class)) {
						if ("documentation".equals(mapEntry.getKey())) {
							result.add(mapEntry);
						}
					}
				}
			}

		}
		return result;
	}

	public Collection<EStringToStringMapEntryImpl> getVisibleConstraintsAnnotations(
			EObject self, DSemanticDiagram diag) {
		Set<EStringToStringMapEntryImpl> result = Sets.newLinkedHashSet();
		for (EModelElement displayed : getDisplayedEModelElements(diag)) {
			if (!(displayed instanceof EAttribute)
					&& !(displayed instanceof EEnumLiteral)
					&& !(displayed instanceof EOperation)) {
				EAnnotation eAnnot = displayed
						.getEAnnotation(ECORE_PACKAGE_NS_URI);
				if (eAnnot != null) {
					for (EStringToStringMapEntryImpl mapEntry : Iterables
							.filter(eAnnot.getDetails(),
									EStringToStringMapEntryImpl.class)) {
						if ("constraints".equals(mapEntry.getKey())) {
							result.add(mapEntry);
						}
					}
				}
			}

		}
		return result;
	}

	public boolean hasNoClassifier(DSemanticDiagram diagram) {
		Iterator<DSemanticDecorator> it = Iterators
				.filter(diagram.getOwnedDiagramElements().iterator(),
						DSemanticDecorator.class);
		while (it.hasNext()) {
			DSemanticDecorator dec = it.next();
			if (dec.getTarget() instanceof EClassifier)
				return true;
		}
		return false;
	}

	public Set<EClass> getDisplayedEClasses(DSemanticDiagram diagram) {
		Set<EClass> result = Sets.newLinkedHashSet();
		Iterator<DSemanticDecorator> it = Iterators.filter(
				diagram.eAllContents(), DSemanticDecorator.class);
		while (it.hasNext()) {
			DSemanticDecorator dec = it.next();
			if (dec.getTarget() instanceof EClass) {
				result.add((EClass) dec.getTarget());
			}
		}
		return result;
	}

	private Set<EClass> getInternalEClasses(DSemanticDiagram diagram) {
		Set<EClass> result = Sets.newLinkedHashSet();
		Iterator<DNodeList> it = Iterators.filter(diagram.eAllContents(),
				DNodeList.class);
		while (it.hasNext()) {
			DNodeList dec = it.next();
			if (dec.getTarget() instanceof EClass) {
				if (dec.getActualMapping() != null
						&& CLASS_DIAGRAM_CLASS_MAPPINGID.equals(dec
								.getActualMapping().getName())) {
					result.add((EClass) dec.getTarget());
				}
			}
		}
		return result;
	}

	public Collection<EClass> getExternalEClasses(EPackage root,
			DSemanticDiagram diagram) {

		Set<EClass> related = Sets.newLinkedHashSet();
		Set<EClass> eClasses = getInternalEClasses(diagram);
		RelatedElementsSwitch relations = new RelatedElementsSwitch();
		for (EClass eClass : eClasses) {
			for (EClass other : Iterables.filter(
					relations.getRelatedElements(eClass), EClass.class)) {
				related.add(other);
			}
		}

		return Sets.difference(related, eClasses);
	}

	public Collection<EReference> getEReferencesToDisplay(EPackage root,
			DSemanticDiagram diagram) {
		// [diagram.getDisplayedEClasses().oclAsType(ecore::EClass).eAllReferences->flatten()/]
		Collection<EClass> eClasses = getDisplayedEClasses(diagram);
		Set<EReference> eRefs = Sets.newLinkedHashSet();
		for (EClass clazz : eClasses) {
			eRefs.addAll(clazz.getEAllReferences());
		}
		return eRefs;
	}

	public Boolean targetIsInterface(EClass clazz, EObject view) {
		if (view instanceof DEdge) {
			EdgeTarget target = ((DEdge) view).getTargetNode();
			if (target instanceof DSemanticDecorator
					&& ((DSemanticDecorator) target).getTarget() instanceof EClass) {
				return ((EClass) ((DSemanticDecorator) target).getTarget())
						.isInterface();
			}
		}
		return false;
	}

	public List<EReference> getEOppositeSemanticElements(EReference ref) {
		Set<EReference> allRefs = Sets.newLinkedHashSet();
		allRefs.add(ref);
		if (ref.getEOpposite() != null)
			allRefs.add(ref.getEOpposite());
		return Ordering.natural()
				.onResultOf(new Function<EReference, String>() {

					public String apply(EReference input) {
						return input.getName();
					}
				}).sortedCopy(allRefs);
	}

	public Collection<EModelElement> getDisplayedEModelElements(
			DSemanticDiagram diagram) {
		Set<EModelElement> modelelements = Sets.newLinkedHashSet();
		Iterator<DSemanticDecorator> it = Iterators.filter(
				Iterators.concat(Iterators.singletonIterator(diagram),
						diagram.eAllContents()), DSemanticDecorator.class);
		while (it.hasNext()) {
			DSemanticDecorator dec = it.next();
			if (dec.getTarget() instanceof EModelElement)
				modelelements.add((EModelElement) dec.getTarget());
		}
		return modelelements;
	}

	public List<EObject> getValidsForDiagram(final EObject element,
			final DSemanticDecorator containerView) {
		Predicate<EObject> validForClassDiagram = new Predicate<EObject>() {

			public boolean apply(EObject input) {
				return input instanceof EPackage
						|| input instanceof EClassifier;
			}
		};
		return allValidSessionElements(element, validForClassDiagram);
	}

	public Collection<EObject> getRelated(EObject firstView,
			List<EObject> allSelectedViews, DDiagram diag) {
		Set<EObject> relateds = Sets.newLinkedHashSet();
		for (DSemanticDecorator decorator : Iterables.filter(allSelectedViews,
				DSemanticDecorator.class)) {
			relateds.addAll(new RelatedElementsSwitch()
					.getRelatedElements(decorator.getTarget()));
		}
		return relateds;
	}

	private List<EObject> allValidSessionElements(EObject cur,
			Predicate<EObject> validForClassDiagram) {
		Session found = SessionManager.INSTANCE.getSession(cur);
		List<EObject> result = Lists.newArrayList();
		if (found != null) {
			for (Resource res : found.getSemanticResources()) {
				if (res.getURI().isPlatformResource()
						|| res.getURI().isPlatformPlugin()) {
					Iterators.addAll(result, Iterators.filter(
							res.getAllContents(), validForClassDiagram));
				}
			}
		}
		return result;
	}

	/**
	 * Gets the containing resource name, or null.
	 * 
	 * @param current
	 *            is the object
	 * @return the resource
	 */
	public String eResourceName(final EObject current) {
		if (current != null && current.eResource() != null) {
			return current.eResource().getURI().lastSegment();
		} else {
			return null;
		}
	}

	/**
	 * Replace spaces by camel case value.
	 * 
	 * @param any
	 * @param from
	 * @return
	 */
	public String toCamelCase(EObject any, String from) {
		if (from != null) {
			StringBuffer buffer = new StringBuffer(from.length());
			for (String word : Splitter.on(CharMatcher.WHITESPACE)
					.trimResults().split(from)) {
				buffer.append(toU1Case(word));
			}
			return buffer.toString();
		}
		return from;
	}

	private String toU1Case(String word) {
		if (word != null && word.length() > 0) {
			return new StringBuilder(word.length())
					.append(Ascii.toUpperCase(word.charAt(0)))
					.append(word.substring(1)).toString();
		}
		return word;
	}

	/**
	 * Computes the label of an EAttribute.
	 */
	public String render(EAttribute attr) {
		return new EAttributeServices().render(attr);
	}

	/**
	 * Performs a "direct edit" operation on an EAttribute.
	 */
	public EAttribute performEdit(EAttribute attr, String editString) {
		return new EAttributeServices().performEdit(attr, editString);
	}

	/**
	 * Computes the label of an EOperation.
	 */
	public String render(EOperation op) {
		return new EOperationServices().render(op);
	}

	public String renderTooltip(EObject current) {
		String result = "";
		Optional<Diagnostic> diag = DiagnosticAttachment.get(current);
		if (diag.isPresent()) {
			result += prettyMessage(diag.get());
		}
		return result;
	}

	private String prettyMessage(Diagnostic diag) {
		String result = "";
		for (Diagnostic child : diag.getChildren()) {
			result += "\n" + severityLabel(child.getSeverity()) + " : "
					+ child.getMessage();
			result += prettyMessage(child);
		}
		return result;
	}

	private String severityLabel(int severity) {
		switch (severity) {
		case Diagnostic.ERROR:
			return "ERROR";
		case Diagnostic.CANCEL:
			return "CANCEL";
		case Diagnostic.INFO:
			return "INFO";
		case Diagnostic.WARNING:
			return "WARNING";
		case Diagnostic.OK:
			return "OK";

		}
		return "UNKNOWN";
	}

	/**
	 * Computes the tooltip of an EOperation.
	 * 
	 * @param op
	 *            the operation to get the tooltip from
	 * @return the tooltip of the given EOperation.
	 */
	public String renderEOperationTooltip(EOperation op) {
		String validationTooltip = renderTooltip(op);
		String operationSignature = new EOperationServices()
				.renderEOperationTooltip(op);
		if (validationTooltip != null && validationTooltip.length() > 0) {
			return validationTooltip + "\n" + operationSignature;
		} else {
			return operationSignature;
		}
	}

	/**
	 * Performs a "direct edit" operation on an EOperation.
	 */
	public EOperation performEdit(EOperation op, String editString) {
		return new EOperationServices().performEdit(op, editString);
	}

	public List<ENamedElement> getAllAssociatedElements(EOperation op) {
		return new EOperationServices().getAllAssociatedElements(op);
	}

	/**
	 * Computes the label of an EReference.
	 */
	public String render(EReference ref) {
		return new EReferenceServices().render(ref);
	}

	public String renderEOpposite(EReference ref) {
		if (ref.getEOpposite() != null) {
			return new EReferenceServices().render(ref.getEOpposite());
		}
		return "";
	}

	/**
	 * Performs a "direct edit" operation on an EReference.
	 */
	public EReference performEdit(EReference ref, String editString) {
		return new EReferenceServices().performEdit(ref, editString);
	}

	/**
	 * Finds a type matching the specified name (case-insensitive) in the same
	 * resource-set as obj, or inside Ecore itself if none could be found.
	 * 
	 * @param obj
	 *            the object defining the context in which to look.
	 * @param name
	 *            the name of the type to look for (case-insensitive). Only
	 *            basic type names are supported (no qualified names).
	 *            Whitespace before or after the name is ignored.
	 * @return the first type found in the resource set or Ecore itself which
	 *         matches the specified name.
	 */
	public EClassifier findTypeByName(EObject obj, String name) {
		EClassifier result = findTypeByName(allRoots(obj), name);
		if (result == null) {
			result = findTypeByNameFrom(EcorePackage.eINSTANCE, name);
		}
		return result;
	}

	/**
	 * Returns the root container; it may be this object itself
	 * 
	 * @param eObject
	 *            the object to get the root container for.
	 * @return the root container.
	 */
	public EObject getRootContainer(EObject eObject) {
		return EcoreUtil.getRootContainer(eObject);
	}

	private EClassifier findTypeByName(Iterable<EObject> roots, String name) {
		for (EObject root : roots) {
			EClassifier result = findTypeByNameFrom(root, name);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

	private EClassifier findTypeByNameFrom(EObject root, String name) {
		if (root instanceof EClassifier
				&& nameMatches((EClassifier) root, name)) {
			return (EClassifier) root;
		}
		for (EObject obj : AllContents.of(root)) {
			if (obj instanceof EClassifier
					&& nameMatches((EClassifier) obj, name)) {
				return (EClassifier) obj;
			}
		}
		return null;
	}

	private boolean nameMatches(EClassifier type, String name) {
		if (type != null && type.getName() != null && name != null) {
			return type.getName().trim().equalsIgnoreCase(name.trim());
		} else {
			return false;
		}
	}

	public Boolean hasError(EObject eObj) {
		if (eObj instanceof EClass || eObj instanceof EStructuralFeature) {
			Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
			DiagnosticAttachment.getOrCreate(eObj, diagnostic);
			return diagnostic.getSeverity() == Diagnostic.ERROR;
		}
		return false;
	}

	public Boolean isEDataType(EObject eObj) {
		return eObj.eClass() == EcorePackage.eINSTANCE.getEDataType();
	}

	public Boolean isDDiagram(EObject any, EObject view) {
		return view instanceof DDiagram;
	}

	public List<EObject> eOperationSemanticElements(EOperation eOp) {
		List result = Lists.newArrayList(Ordering.natural()
				.onResultOf(new Function<EParameter, String>() {

					public String apply(EParameter arg0) {
						return arg0.getName();
					}
				}).sortedCopy(eOp.getEParameters()));
		result.add(0, eOp);
		return result;
	}

	public Boolean viewContainerNotSemanticContainer(EObject self,
			DSemanticDiagram diag) {
		return diag.getTarget() != self.eContainer();
	}

	public Boolean noEOpposite(EReference ref) {
		return ref.getEOpposite() == null;
	}

	public boolean hasNoDocAnnotation(EObject eObj) {
		// Error[eAnnotations.details->select(key = 'documentation')->size() =
		// 0/]
		if (eObj instanceof EModelElement) {
			return EcoreUtil.getDocumentation((EModelElement) eObj) == null;
		}
		return true;
	}

	/**
	 * Shows the Properties View. (See Double Click Action in Design ViewPoint)
	 * 
	 * @param object
	 *            Any EObject
	 */
	public void showPropertiesViewAction(EObject object) {
		try {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getActivePage()
					.showView("org.eclipse.ui.views.PropertySheet");
		} catch (PartInitException exception) {
			EcoreEditorPlugin.INSTANCE.log(exception);
		}
	}

	public EEnumLiteral arrowsFillDiamond(EObject any) {
		return DiagramPackage.eINSTANCE.getEdgeArrows().getEEnumLiteral(
				"FillDiamond");
	}

	public EEnumLiteral fontFormatBold(EObject any) {
		return ViewpointPackage.eINSTANCE.getFontFormat().getEEnumLiteral(
				"bold");
	}

	public void openClassDiagramContextHelp(EObject any) {
//		try {
//			openContextHelp(any,
//					"org.eclipse.emf.ecoretools.design.ClassDiagram");
//		} catch (IOException e) {
//			EcoreEditorPlugin.INSTANCE.log(e);
//		}
	}

	public void openContextHelp(EObject any, final String contextID)
			throws IOException {
		if (Display.getDefault() != null)
			Display.getDefault().asyncExec(new Runnable() {

				public void run() {
					if (PlatformUI.getWorkbench() != null
							&& PlatformUI.getWorkbench()
									.getActiveWorkbenchWindow() != null
							&& PlatformUI.getWorkbench()
									.getActiveWorkbenchWindow().getShell() != null) {
						PlatformUI.getWorkbench().getActiveWorkbenchWindow()
								.getShell();
						PlatformUI
								.getWorkbench()
								.getHelpSystem()
								.setHelp(
										PlatformUI.getWorkbench()
												.getActiveWorkbenchWindow()
												.getShell(), contextID);
						PlatformUI.getWorkbench().getHelpSystem()
								.displayDynamicHelp();

					}
				}
			});
	}

	public void reconnectEReference(EObject element, DEdge edgeAfterReconnect) {
		if (edgeAfterReconnect.getSourceNode() instanceof DSemanticDecorator
				&& edgeAfterReconnect.getTargetNode() instanceof DSemanticDecorator) {

			EObject newSource = ((DSemanticDecorator) edgeAfterReconnect
					.getSourceNode()).getTarget();
			EObject newTarget = ((DSemanticDecorator) edgeAfterReconnect
					.getTargetNode()).getTarget();
			if (element instanceof EReference) {
				EReference eRef = (EReference) element;
				if (newSource instanceof EClass) {
					EClass srcClass = (EClass) newSource;

					if (eRef.eContainer() != srcClass) {
						srcClass.getEStructuralFeatures().add(eRef);
					}

					if (newTarget instanceof EClass) {
						EClass targetClass = (EClass) newTarget;
						if (eRef.getEType() != newTarget) {
							eRef.setEType(targetClass);
						}
					} else if (newTarget instanceof ETypeParameter) {
						if (eRef.getEType() != newTarget) {
							EGenericsServices.setETypeWithGenerics(eRef,
									newTarget);
						}
					}

				}

			}
		}
	}
}