/*******************************************************************************
 * Copyright (c) 2013, 2018 CEA LIST 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 (CEA LIST) - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.examples.validity.locator;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.emf.validation.validity.LeafConstrainingNode;
import org.eclipse.ocl.examples.emf.validation.validity.Result;
import org.eclipse.ocl.examples.emf.validation.validity.Severity;
import org.eclipse.ocl.examples.emf.validation.validity.ValidatableNode;
import org.eclipse.ocl.examples.emf.validation.validity.locator.ConstraintLocator;
import org.eclipse.ocl.examples.emf.validation.validity.manager.ConstrainingURI;
import org.eclipse.ocl.examples.emf.validation.validity.manager.TypeURI;
import org.eclipse.ocl.examples.emf.validation.validity.manager.ValidityManager;
import org.eclipse.ocl.examples.emf.validation.validity.manager.ValidityModel;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.evaluation.AbstractConstraintEvaluator;
import org.eclipse.ocl.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal.EnvironmentFactoryInternalExtension;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.utilities.ParserException;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageImport;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.ValueSpecification;

public class UMLConstraintLocator extends AbstractPivotConstraintLocator
{
	public static @NonNull UMLConstraintLocator INSTANCE = new UMLConstraintLocator();

	protected void appendPath(@NonNull StringBuilder s, @NonNull NamedElement eObject) {
		EObject eContainer = eObject.eContainer();
		if (eContainer instanceof NamedElement) {
			appendPath(s, (NamedElement)eContainer);
			s.append("::");
		}
		s.append(eObject.getName());
	}

	@Override
	public @NonNull Set<@NonNull TypeURI> getAllTypes(@NonNull ValidityManager validityManager, @NonNull EObject constrainingType) {
		if (constrainingType instanceof org.eclipse.uml2.uml.Class) {
			Set<@NonNull TypeURI> allTypes = new HashSet<@NonNull TypeURI>();
			allTypes.add(validityManager.getTypeURI(constrainingType));
			if (constrainingType instanceof org.eclipse.uml2.uml.Class) {
				getAllTypes(allTypes, validityManager, ((org.eclipse.uml2.uml.Class)constrainingType).getSuperClasses());
			}
			return allTypes;
		}
		else {
			return super.getAllTypes(validityManager, constrainingType);
		}
	}

	private void getAllTypes(Set<@NonNull TypeURI> knownTypes, @NonNull ValidityManager validityManager, Iterable<org.eclipse.uml2.uml.Class> moreTypes) {
		for (org.eclipse.uml2.uml.Class anotherType : moreTypes) {
			if ((anotherType != null) && knownTypes.add(validityManager.getTypeURI(anotherType))) {
				getAllTypes(knownTypes, validityManager, anotherType.getSuperClasses());
			}
		}
	}

	@Override	// FIXME is it getConstrainingURI or getTypeURI that needs the overload - no JUnit test uses the code
	public @Nullable ConstrainingURI getConstrainingURI(@NonNull EObject eObject) {
		EObject eContainer = eObject;
		for ( ; true; eContainer = eContainer.eContainer()) {
			if (eContainer == null) {
				return null;
			}
			if (eContainer instanceof Package) {
				break;
			}
		}
		String nsURI = null;
		Stereotype appliedStereotype = ((Package)eContainer).getAppliedStereotype("Ecore::EPackage");
		if (appliedStereotype != null) {
			Object value = ((Package)eContainer).getValue(appliedStereotype, "nsURI");
			if (value != null) {
				nsURI = value.toString();
			}
		}
		if (nsURI == null) {
			nsURI = ((Package)eContainer).getURI();
		}
		if (nsURI == null) {
			return null;
		}
		Resource resource = eObject.eResource();
		if (resource == null) {
			return null;
		}
		String uriFragment = resource.getURIFragment(eObject);
		if (uriFragment == null) {
			return null;
		}
		if (!uriFragment.startsWith("//")) {
			uriFragment = "//" + uriFragment;		// FIXME regularize this ?? UML2Ecore
		}
		@NonNull URI constrainingURI = URI.createURI(nsURI).appendFragment(uriFragment);
		return new ConstrainingURI(constrainingURI);
	}

	@Override
	public @Nullable Map<@NonNull EObject, @NonNull List<@NonNull LeafConstrainingNode>> getConstraints(@NonNull ValidityModel validityModel,
			@NonNull EPackage ePackage, @NonNull Set<@NonNull Resource> resources, @NonNull Monitor monitor) {
		Map<@NonNull EObject, @NonNull List<@NonNull LeafConstrainingNode>> map = null;
		for (@NonNull Resource resource : resources) {
			if (monitor.isCanceled()) {
				return null;
			}
			for (TreeIterator<EObject> tit = resource.getAllContents(); tit.hasNext(); ) {
				EObject eObject = tit.next();
				if (eObject instanceof Constraint) {
					Constraint umlConstraint = (Constraint)eObject;
					Element contextElement = umlConstraint.getContext();
					if (contextElement instanceof Type) {
						@NonNull String label = String.valueOf(umlConstraint.getName());
						/*					LeafConstrainingNode constraint = validityModel.createLeafConstrainingNode();
						constraint.setConstraintLocator(this);
						constraint.setConstrainingObject(umlConstraint);
						constraint.setLabel(label);
						ConstrainingNode constrainingNode = validityModel.getConstrainingNode(constrainedElement);
						constrainingNode.getChildren().add(constraint);
						if (map == null) {
							map = new HashMap<EModelElement, List<LeafConstrainingNode>>();
						}
						List<LeafConstrainingNode> constraints = map.get(constrainedElement);
						if (constraints == null) {
							constraints = new ArrayList<LeafConstrainingNode>();
							map.put(constrainedElement, constraints);
						}
						constraints.add(constraint); */
						//						EClass eC = constrainedElement.eClass();
						map = createLeafConstrainingNode(map, validityModel, contextElement, umlConstraint, label);
					}
				}
				if (monitor.isCanceled()) {
					return null;
				}
			}
		}
		return map;
	}

	@Override
	public @Nullable Collection<@NonNull Resource> getImports(@NonNull EPackage ePackage, @NonNull Resource resource) {
		Set<@NonNull Resource> imports = new HashSet<@NonNull Resource>();
		for (TreeIterator<EObject> tit = resource.getAllContents(); tit.hasNext(); ) {
			EObject eObject = tit.next();
			if (eObject instanceof PackageImport) {
				PackageImport umlPackageImport = (PackageImport)eObject;
				Package importedPackage = umlPackageImport.getImportedPackage();
				if (importedPackage != null) {
					Resource eResource = importedPackage.eResource();
					if (eResource != null) {
						imports.add(eResource);
					}
				}
				//				tit.prune();
			}
			//			else if (eObject instanceof Type) {
			//				tit.prune();
			//			}
			Resource eResource = eObject.eClass().eResource();
			if (eResource != null) {
				imports.add(eResource);
			}
		}
		return imports;
	}

	@Override
	public @NonNull ConstraintLocator getInstance() {
		return INSTANCE;
	}

	@Override
	public @NonNull String getLabel(@NonNull EModelElement eObject) {
		if (eObject instanceof NamedElement) {			// FIXME debugging - remove UML dependency
			StringBuilder s = new StringBuilder();
			appendPath(s, (NamedElement)eObject);
			return s.toString();
		}
		else {
			return super.getLabel(eObject);
		}
	}

	@Override
	public @NonNull String getName() {
		return "UML Constraints";
	}

	@Override
	public @Nullable String getSourceExpression(@NonNull LeafConstrainingNode node) {
		Object constrainingObject = node.getConstrainingObject();
		if (!(constrainingObject instanceof Constraint)) {
			return null;
		}
		ValueSpecification specification = ((Constraint)constrainingObject).getSpecification();
		if (!(specification instanceof OpaqueExpression)) {
			return null;
		}
		List<String> bodies = ((OpaqueExpression)specification).getBodies();
		return bodies.size() > 0 ? bodies.get(0) : null;
	}

	@Override
	public @Nullable Resource getSourceResource(@NonNull LeafConstrainingNode node) {
		Object constrainingObject = node.getConstrainingObject();
		if (!(constrainingObject instanceof EObject)) {
			return null;
		}
		return ((EObject)constrainingObject).eResource();
	}

	@Override
	public @Nullable TypeURI getTypeURI(@NonNull EObject eObject) {
		EObject eContainer = eObject;
		for ( ; true; eContainer = eContainer.eContainer()) {
			if (eContainer == null) {
				return null;
			}
			if (eContainer instanceof Package) {
				break;
			}
		}
		String nsURI = null;
		Stereotype appliedStereotype = ((Package)eContainer).getAppliedStereotype("Ecore::EPackage");
		if (appliedStereotype != null) {
			Object value = ((Package)eContainer).getValue(appliedStereotype, "nsURI");
			if (value != null) {
				nsURI = value.toString();
			}
		}
		if (nsURI == null) {
			nsURI = ((Package)eContainer).getURI();
		}
		if (nsURI == null) {
			return null;
		}
		Resource resource = eObject.eResource();
		if (resource == null) {
			return null;
		}
		String uriFragment = resource.getURIFragment(eObject);
		if (!uriFragment.startsWith("//")) {
			uriFragment = "//" + uriFragment;		// FIXME regularize this ?? UML2Ecore
		}
		@NonNull URI typeURI = URI.createURI(nsURI).appendFragment(uriFragment);
		return new TypeURI(typeURI);
	}

	@Override
	public @Nullable Set<@NonNull TypeURI> getTypeURIs(@NonNull ValidityManager validityManager, @NonNull EObject validatableObject) {
		EClass eClass = validatableObject.eClass();
		if (eClass != null) {
			EAnnotation eAnnotation = eClass.getEAnnotation("http://www.eclipse.org/uml2/2.0.0/UML");
			if ((eAnnotation != null) && (eAnnotation.getReferences().size() > 0)) { // Stereotype application
				EObject umlClass = eAnnotation.getReferences().get(0);
				if (umlClass != null) {
					Set<@NonNull TypeURI> allTypeURIs = new HashSet<@NonNull TypeURI>();
					TypeURI typeURI = validityManager.getTypeURI(umlClass);
					allTypeURIs.add(typeURI);
					return allTypeURIs;
				}
			}
		}
		if (validatableObject instanceof InstanceSpecification) {
			Set<@NonNull TypeURI> allTypeURIs = new HashSet<@NonNull TypeURI>();
			for (org.eclipse.uml2.uml.Classifier umlClassifier : ((InstanceSpecification)validatableObject).getClassifiers()) {
				if (umlClassifier != null) {
					TypeURI typeURI = validityManager.getTypeURI(umlClassifier);
					allTypeURIs.add(typeURI);
				}
			}
			return allTypeURIs;
		}
		return null;
	}

	@Override
	public void validate(@NonNull Result result, @NonNull ValidityManager validityManager, @Nullable Monitor monitor) {
		ValidatableNode validatableNode = result.getValidatableNode();
		EObject contextObject = validatableNode.getConstrainedObject();
		LeafConstrainingNode leafConstrainingNode = result.getLeafConstrainingNode();
		org.eclipse.uml2.uml.Constraint umlConstraint = (org.eclipse.uml2.uml.Constraint)leafConstrainingNode.getConstrainingObject();
		if (umlConstraint == null) {
			return;
		}
		EnvironmentFactoryInternalExtension environmentFactory = (EnvironmentFactoryInternalExtension) PivotUtilInternal.findEnvironmentFactory(umlConstraint);
		if (environmentFactory == null) {
			Resource eResource = umlConstraint.eResource();
			if (eResource == null) {
				return;
			}
			environmentFactory = (EnvironmentFactoryInternalExtension) PivotUtilInternal.getEnvironmentFactory(eResource);
		}
		PivotMetamodelManager metamodelManager = environmentFactory.getMetamodelManager();
		Severity severity = Severity.UNKNOWN;
		try {
			final org.eclipse.ocl.pivot.Constraint pivotConstraint = environmentFactory.getASOf(org.eclipse.ocl.pivot.Constraint.class, umlConstraint);
			if (pivotConstraint == null) {
				throw new ParserException("Failed to create pivot Constraint");
			}
			ResourceSet resourceSet = contextObject.eResource().getResourceSet();
			if (resourceSet != null) {
				ExpressionInOCL query = getQuery(metamodelManager, pivotConstraint);
				EvaluationVisitor evaluationVisitor = createEvaluationVisitor(environmentFactory, query, contextObject, monitor);
				AbstractConstraintEvaluator<Diagnostic> constraintEvaluator = new AbstractConstraintLocator(metamodelManager, query, contextObject)
				{
					@Override
					protected String getObjectLabel() {
						org.eclipse.ocl.pivot.Type type = PivotUtil.getContainingType(pivotConstraint);
						return type != null ? type.getName() : "??";
					}
				};
				@Nullable Diagnostic diagnostic = constraintEvaluator.evaluate(evaluationVisitor);
				result.setDiagnostic(diagnostic);
				severity = diagnostic != null ? getSeverity(diagnostic) : Severity.OK;
			}
		} catch (Throwable e) {
			result.setException(e);
			severity = Severity.FATAL;
		} finally {
			result.setSeverity(severity);
		}
	}
}
