/*******************************************************************************
 * Copyright (c) 2006, 2018 IBM Corporation, Zeligsoft Inc., 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:
 *   IBM - Initial API and implementation
 *   Zeligsoft - Bugs 252600, 251808
 *******************************************************************************/

package org.eclipse.ocl.uml;

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

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClassifier;
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.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.ocl.AbstractEnvironment;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EnvironmentFactory;
import org.eclipse.ocl.TypeResolver;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.lpg.FormattingHelper;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.uml.internal.OCLFactoryImpl;
import org.eclipse.ocl.uml.internal.OCLStandardLibraryImpl;
import org.eclipse.ocl.uml.internal.UMLForeignMethods;
import org.eclipse.ocl.uml.internal.UMLReflectionImpl;
import org.eclipse.ocl.uml.util.OCLUMLUtil;
import org.eclipse.ocl.utilities.OCLFactory;
import org.eclipse.ocl.utilities.UMLReflection;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.CallOperationAction;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Feature;
import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
import org.eclipse.uml2.uml.ParameterEffectKind;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Region;
import org.eclipse.uml2.uml.SendSignalAction;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.Vertex;

/**
 * Implementation of the {@link Environment} for parsing OCL expressions on UML
 * models. The <code>UMLEnvironment</code> uses a client-supplied resource set
 * to look up UML {@link Package}s in UML resources. It also uses an
 * {@link EPackage} registry to find the corresponding Ecore definitions of
 * packages when evaluating expressions on instances of the UML model (in the
 * case of evaluation on UML2-generated API objects).
 * 
 * @author Christian W. Damus (cdamus)
 */
public class UMLEnvironment
    extends
    AbstractEnvironment<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, Class, EObject> {
	
	/**
	 * The namespace URI of the UML representation of the OCL Standard Library.
	 * 
	 * @since 2.0
	 */
	public static final String OCL_STANDARD_LIBRARY_NS_URI = "http://www.eclipse.org/ocl/1.1.0/oclstdlib.uml"; //$NON-NLS-1$
    
    static final String ANNOTATION_SOURCE = org.eclipse.ocl.uml.UMLPackage.eNS_URI;
    
    private static OCLStandardLibraryImpl standardLibrary;

    private UMLReflection<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint> reflection;

    /** The resource set for package lookups. */
    private ResourceSet resourceSet;

    /** The package registry for Ecore definition lookups. */
    private EPackage.Registry registry;

    private EnvironmentFactory<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, Class, EObject> factory;

    private TypeResolver<Classifier, Operation, Property> typeResolver;

    private Package umlMetamodel;

    private Map<List<String>, Classifier> classifierCache = new java.util.HashMap<List<String>, Classifier>();

    private Map<List<String>, Package> packageCache = new java.util.HashMap<List<String>, Package>();

    /**
     * Initializes me with a package registry for looking up the Ecore
     * representations of UML packages and a resource set for looking up UML
     * packages in UML resources.
     * 
     * @param registry
     *            the Ecore package registry to use
     * @param rset
     *            the resource set to use
     */
    protected UMLEnvironment(EPackage.Registry registry, ResourceSet rset) {
        this.registry = registry;
        resourceSet = rset;

        typeResolver = createTypeResolver();
    }

    /**
     * Initializes me with a package registry for looking up the Ecore
     * representations of UML packages, a resource set for looking up UML
     * packages in UML resources, and a resource from which to load myself.
     * 
     * @param registry
     *            the Ecore package registry to use
     * @param rset
     *            the resource set to use
     * @param resource
     *            my resource for persistence
     */
    protected UMLEnvironment(EPackage.Registry registry, ResourceSet rset,
            Resource resource) {
        this.registry = registry;
        resourceSet = rset;

        typeResolver = createTypeResolver(resource);
    }

    /**
     * Initializes me with a parent environment. I inherit my package registry,
     * resource set, and resource from it.
     * 
     * @param parent
     *            my parent environment
     */
    protected UMLEnvironment(
            Environment<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, Class, EObject> parent) {

        super((UMLEnvironment) parent);

        UMLEnvironment uparent = (UMLEnvironment) parent;

        if (uparent != null) {
            this.registry = uparent.registry;
            resourceSet = uparent.resourceSet;
            typeResolver = uparent.getTypeResolver();
        } else {
            this.registry = (EPackage.Registry.INSTANCE);
            resourceSet = new ResourceSetImpl();
            typeResolver = createTypeResolver();
        }
    }

    // implements the inherited specification
    public EnvironmentFactory<org.eclipse.uml2.uml.Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, org.eclipse.uml2.uml.Class, EObject> getFactory() {
        if (factory != null) {
            return factory;
        }

        if (getInternalParent() != null) {
            factory = getInternalParent().getFactory();
            if (factory != null) {
                return factory;
            }
        }

        // obtain a reasonable default factory
        factory = new UMLEnvironmentFactory(getResourceSet());

        return factory;
    }

    /**
     * Sets the factory that created me. This method should only be invoked by
     * that factory.
     * 
     * @param factory
     *            my originating factory
     */
    protected void setFactory(
            EnvironmentFactory<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, Class, EObject> factory) {
        this.factory = factory;
    }

    /**
     * Looks up the Ecore definition of the specified UML classifier, using the
     * specified <code>element</code> as a context for finding profile
     * applications in the case that the classifier is a stereotype or some
     * other type in a {@link Profile}.  Finding the Ecore definition of a profile
     * type requires finding the actual applied version of the profile.
     * 
     * @param type a UML classifier
     * @param element an element in the context of which the OCL evaluation
     *     is being performed
     * @return the corresponding Ecore classifier, or <code>null</code> if not
     *     found
     * @since 3.0
     */
	public EClassifier getEClassifier(Classifier type, Object element) {
		return OCLUMLUtil.getEClassifier(type, element, registry);
	}
    
//    /**
//     * Obtains my EPackage registry, for looking up the Ecore correspondents
//     * of UML metamodel elements when working with instances of generated Java
//     * types.
//     * 
//     * @return my EPackage registry
//     */
//    EPackage.Registry getEPackageRegistry() {
//        return registry;
//    }

    // implements the inherited specification
    public void setParent(
            Environment<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint, Class, EObject> env) {
        super.setParent((UMLEnvironment) env);
    }

    // implements the inherited specification
    public OCLStandardLibrary<Classifier> getOCLStandardLibrary() {
        if (standardLibrary == null) {
            standardLibrary = OCLStandardLibraryImpl.INSTANCE;
        }

        return standardLibrary;
    }

    /**
     * Obtains the resource set in which I look for UML packages when resolving
     * package names.
     * 
     * @return my resource set
     */
    protected final ResourceSet getResourceSet() {
        return resourceSet;
    }

    /**
     * Obtains the UML metamodel library, loaded in my resource set.
     * 
     * @return the UML metamodel
     */
    protected Package getUMLMetamodel() {
        if (umlMetamodel == null) {
            if (getFactory() instanceof UMLEnvironmentFactory) {
                umlMetamodel = ((UMLEnvironmentFactory) getFactory())
                    .getUMLMetamodel();
            } else {
                umlMetamodel = OCLUMLUtil.getUMLMetamodel(getResourceSet());
            }
        }

        return umlMetamodel;
    }

    // implements the inherited specification
    public TypeResolver<Classifier, Operation, Property> getTypeResolver() {
        return typeResolver;
    }

    // implements the inherited specification
    public OCLFactory getOCLFactory() {
        return OCLFactoryImpl.INSTANCE;
    }

    // implements the inherited specification
    public UMLReflection<Package, Classifier, Operation, Property, EnumerationLiteral, Parameter, State, CallOperationAction, SendSignalAction, Constraint> getUMLReflection() {
        if (reflection == null) {
            reflection = new UMLReflectionImpl(this);
        }

        return reflection;
    }

    /**
     * Creates a new type resolver for use with this environment, persisted
     * in a default resource. 
     * 
     * @return a new type resolver
     * 
     * @deprecated Override the {@link #createTypeResolver(Resource)} method,
     *     instead, handling the case where the resource is <code>null</code>
     */
    @Deprecated
    protected TypeResolver<Classifier, Operation, Property> createTypeResolver() {
        return createTypeResolver(null);
    }
    
    /**
     * <p>
     * Creates a new type resolver for use with this environment.
     * </p><p>
     * Subclasses may override.
     * </p>
     * 
     * @param resource the resource for the type resolver's persistence
     * @return a new type resolver
     * 
     * @since 1.2
     */
    protected TypeResolver<Classifier, Operation, Property> createTypeResolver(Resource resource) {
        return new TypeResolverImpl(this, resource);
    }

    /**
     * {@inheritDoc}
     * <p>
     * Implements the inherited specification by looking in my resource set for
     * a resource containing the specified package.
     * </p>
     */
    public org.eclipse.uml2.uml.Package lookupPackage(List<String> path) {
        Package tryCache = packageCache.get(path);
        if (tryCache != null) {
            return tryCache;
        }

        Package pkg = null;
        Package currPkg = getContextPackage();

        // Check whether this package is in the default package
        if (currPkg != null) {
            List<String> lookup = path;

            while (currPkg != null) {
                pkg = currPkg;

                for (int i = 0; i < lookup.size(); i++) {
                    String name = lookup.get(i);
                    pkg = UMLForeignMethods.getNestedPackage(pkg, name);

                    if (pkg == null) {
                        break;
                    }
                }

                if (pkg != null) {
                    packageCache.put(path, pkg);
                    return pkg;
                }

                if ((currPkg == getContextPackage()) && (lookup.size() > 0)
                    && UMLForeignMethods.isNamed(lookup.get(0), currPkg)) {
                    // handle the case where the first part of the qualified
                    // name matches the context package name
                    lookup = lookup.subList(1, lookup.size());
                } else {
                    lookup = path;
                    currPkg = currPkg.getNestingPackage();
                }
            }
        }

        // Check whether this package exists in the resource set
        Package result = OCLUMLUtil.findPackage(path, getResourceSet());
        packageCache.put(path, result);
        return result;
    }

    // implements the inherited specification
    public Classifier lookupClassifier(List<String> names) {
        Classifier tryCache = classifierCache.get(names);
        if (tryCache != null) {
            return tryCache;
        }

        Namespace ns = null;
        Namespace currNs = getContextPackage();

        if (names.size() > 1) {
            List<String> lookup = names;

            // Check whether this package is in the default package
            if (currNs != null) {
                while (currNs != null) {

                    ns = currNs;
                    int last = lookup.size() - 1;

                    for (int i = 0; i < last; i++) {
                        String name = lookup.get(i);
                        ns = (Namespace) UMLForeignMethods.getMember(ns, name,
                            UMLPackage.Literals.NAMESPACE);

                        if (ns == null) {
                            break;
                        }
                    }

                    if (ns != null) {
                        String name = lookup.get(last);

                        Classifier member = (Classifier) UMLForeignMethods
                            .getMember(ns, name, UMLPackage.Literals.CLASSIFIER);

                        if (member != null) {
                            classifierCache.put(names, member);
                            return member;
                        }
                    }

                    if ((currNs == getContextPackage()) && (lookup.size() > 1)
                        && UMLForeignMethods.isNamed(lookup.get(0), currNs)) {
                        // handle the case where the first part of the qualified
                        // name matches the context package name
                        lookup = lookup.subList(1, lookup.size());
                    } else {
                        lookup = names;
                        currNs = currNs.getNamespace();
                    }
                }
            }

            // Check whether this package exists
            List<String> newNames = names.subList(0, names.size() - 1);
            ns = OCLUMLUtil.findNamespace(newNames, getResourceSet());
            if (ns == null) {
                return null;
            }

            String name = names.get(names.size() - 1);
            Classifier member = (Classifier) UMLForeignMethods.getMember(ns,
                name, UMLPackage.Literals.CLASSIFIER);

            if (member != null) {
                classifierCache.put(names, member);
                return member;
            }

            return member;
        } else if (getContextPackage() != null) {
            String name = names.get(0);
            Classifier result = null;
            while (currNs != null) {
                result = (Classifier) UMLForeignMethods.getMember(currNs, name,
                    UMLPackage.Literals.CLASSIFIER);

                if (result != null) {
                    classifierCache.put(names, result);
                    return result;
                }

                currNs = currNs.getNamespace();
            }
        }

        return null;
    }

    @Override
    protected void findNonNavigableAssociationEnds(Classifier classifier,
            String name, List<Property> ends) {
        
        EList<Association> associations = UMLForeignMethods.getAllAssociations(classifier);

        // search for non-navigable, named ends
        for (Association next : associations) {
            if (next.isBinary()) {
                Property end = next.getMemberEnd(name, null);

				if ((end != null)
					&& OCLUMLUtil
						.isNonNavigableAssocationEndOf(end, classifier)) {
					
					ends.add(end);
				}
            }
        }
    }
    
    @Override
    protected void findUnnamedAssociationEnds(Classifier classifier, String name,
            List<Property> ends) {
        
        EList<Association> associations = UMLForeignMethods.getAllAssociations(classifier);

        for (Association next : associations) {
            if (next.isBinary()) {
                for (Property end : next.getMemberEnds()) {
                    if (isUnnamed(end)) {
                        Type type = end.getType();
						if ((type != null)
							&& initialLower(type).equals(name)
							&& OCLUMLUtil.isNonNavigableAssocationEndOf(end,
								classifier)) {
							
							ends.add(end);
						}
                    }
                }
            }
        }
    }
    
    /**
     * Queries whether the specified association end has no name.
     * 
     * @param associationEnd an association end
     * 
     * @return whether it is unnamed
     */
    protected boolean isUnnamed(Property associationEnd) {
        return associationEnd.getName() == null;
    }

    // implements the inherited specification
    public List<State> getStates(Classifier owner, List<String> pathPrefix) {
        EList<State> result = new BasicEList.FastCompare<State>();

        collectStates(owner, pathPrefix, result);

        // search supertypes
        for (Classifier general : owner.allParents()) {
            collectStates(general, pathPrefix, result);
        }

        // now, filter out redefinitions, in case our prefix match found
        // states that are redefined by other matches (as an instance of the
        // owner type cannot be in a state that is redefined by a more
        // specific state)
        Set<State> redefinitions = new java.util.HashSet<State>();
        for (State s : result) {
            State redef = s.getRedefinedState();

            while (redef != null) {
                redefinitions.add(redef);
                redef = redef.getRedefinedState();
            }
        }

        result.removeAll(redefinitions);

        return result;
    }

    /**
     * Finds all states in the specified owner type that match the given path
     * name prefix and add them to the accumulator list.
     * 
     * @param owner
     *            the owner type
     * @param pathPrefix
     *            partial qualified name, specifying the parent of the states to
     *            be collected
     * @param states
     *            a list of states directly owned by the namespace indicated by
     *            path prefix, within the owner type
     */
    private void collectStates(Classifier owner, List<String> pathPrefix,
            List<State> states) {
        if (owner instanceof BehavioredClassifier) {
            List<Behavior> behaviors = ((BehavioredClassifier) owner)
                .getOwnedBehaviors();

            for (Behavior b : behaviors) {
                if (b instanceof StateMachine) {
                    collectStates((StateMachine) b, pathPrefix, states);
                }
            }
        }
    }

    private void collectStates(StateMachine machine, List<String> pathPrefix,
            List<State> states) {
        if (pathPrefix.isEmpty()) {
            for (Region r : machine.getRegions()) {
                collectStates(r, pathPrefix, states);
            }
        } else {
            String firstName = pathPrefix.get(0);

            if (UMLForeignMethods.isNamed(firstName, machine)) {
                // we are allowed to qualify the states by machine name
                pathPrefix = pathPrefix.subList(1, pathPrefix.size());
            }

            for (Region r : machine.getRegions()) {
                collectStates(r, pathPrefix, states);
            }
        }
    }

    private void collectStates(Region region, List<String> pathPrefix,
            List<State> states) {
        if (pathPrefix.isEmpty()) {
            // terminus of the recursion: get all the states in this region
            for (Vertex v : region.getSubvertices()) {
                if (v instanceof State) {
                    states.add((State) v);
                }
            }
        } else {
            String firstName = pathPrefix.get(0);

            Vertex v = UMLForeignMethods.getSubvertex(region, firstName);
            if (v instanceof State) {
                State state = (State) v;

                if (state.isComposite()) {
                    // recursively search the regions of this composite state
                    pathPrefix = pathPrefix.subList(1, pathPrefix.size());

                    for (Region r : state.getRegions()) {
                        collectStates(r, pathPrefix, states);
                    }
                }
            }
        }
    }

    // implements the inherited specification
    public Property defineAttribute(Classifier owner,
            Variable<Classifier, Parameter> variable, Constraint constraint) {
		resetTypeCaches();		
        Property result;

        String name = variable.getName();
        Classifier type = variable.getType();

        result = UMLFactory.eINSTANCE.createProperty();

        result.addKeyword(UMLReflection.OCL_HELPER);

        result.setName(name);
        result.setType(type);

        annotate(result, constraint);

        addHelperProperty(owner, result);

        return result;
    }

    // implements the inherited specification
    public Operation defineOperation(Classifier owner, String name,
            Classifier type, List<Variable<Classifier, Parameter>> params,
            Constraint constraint) {
		resetTypeCaches();		
        Operation result = UMLFactory.eINSTANCE.createOperation();

        result.addKeyword(UMLReflection.OCL_HELPER);

        result.setName(name);
        result.setType(type == null ? getOCLStandardLibrary().getOclVoid()
            : type);
        result.setIsQuery(true); // OCL can only define queries

        for (Variable<Classifier, Parameter> next : params) {
            Parameter param = UMLFactory.eINSTANCE.createParameter();
            param.setName(next.getName());
            param.setType(next.getType() == null ? getOCLStandardLibrary()
                .getOclVoid()
                : next.getType());

            param.setDirection(ParameterDirectionKind.IN_LITERAL);
            param.setEffect(ParameterEffectKind.READ_LITERAL);

            result.getOwnedParameters().add(param);
        }

        annotate(result, constraint);

        addHelperOperation(owner, result);

        return result;
    }
    
    private void annotate(Feature feature, Constraint definition) {
        EAnnotation annotation = feature.getEAnnotation(ANNOTATION_SOURCE);
        
        if (annotation == null) {
            annotation = feature.createEAnnotation(ANNOTATION_SOURCE);
        }
        
        annotation.getReferences().add(definition);
    }

    // implements the inherited specification
    public void undefine(Object feature) {
        Constraint definition = getDefinition(feature);

        if (definition == null) {
            throw new IllegalArgumentException(
                "not an additional feature: " + feature); //$NON-NLS-1$
        }

        EcoreUtil.remove((EObject) feature);
        EcoreUtil.remove(definition);

        definition.getConstrainedElements().clear();
		resetTypeCaches();		
    }

    // implements the inherited specification
    public Constraint getDefinition(Object feature) {
        Constraint result = null;
        Feature umlFeature = (Feature) feature;

        Classifier owner = (Classifier) umlFeature.getOwner();

        if (owner instanceof Class) {
            Classifier shadowed = ((TypeResolverImpl) getTypeResolver())
                .getShadowedClassifier(owner);

            if (shadowed != null) {
                owner = shadowed;
            }
        }

        if (owner != null) {
            if (feature instanceof EModelElement) {
                EAnnotation annotation = ((EModelElement) feature).getEAnnotation(
                    ANNOTATION_SOURCE);
                if (annotation != null) {
                    result = (Constraint) EcoreUtil.getObjectByType(
                        annotation.getReferences(),
                        UMLPackage.Literals.CONSTRAINT);
                }
            }
            
            if (result == null) {
                // backward compatibility for existing serializations
                for (Constraint ct : owner.getOwnedRules()) {
                    if (ct.getKeywords().contains(UMLReflection.DEFINITION)
                        && ct.getConstrainedElements().contains(umlFeature)) {
                        result = ct;
                        break;
                    }
                }
            }
        }

        return result;
    }

    // implements the inherited specification
    public boolean isInPostcondition(
            org.eclipse.ocl.expressions.OCLExpression<Classifier> exp) {

        Constraint constraint = null;
        EObject parent = exp;
        while (parent != null) {
            if (parent instanceof Constraint) {
                constraint = (Constraint) parent;
                break;
            }

            parent = parent.eContainer();
        }

        return (constraint != null)
            && (!constraint.getKeywords().isEmpty())
            && UMLReflection.POSTCONDITION.equals(constraint.getKeywords().get(
                0));
    }
    
    /**
     * I provide a custom formatting helper for UML metamodel.
     * 
     * @since 1.2
     */
    @Override
    public FormattingHelper getFormatter() {
        return UMLFormattingHelper.INSTANCE;
    }
}
