/*******************************************************************************
 * Copyright (c) 2009, 2012 SAP AG 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:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.instanceScope;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.OperationCallExp;
import org.eclipse.ocl.ecore.TypeExp;
import org.eclipse.ocl.ecore.Variable;
import org.eclipse.ocl.ecore.impl.TypeExpImpl;
import org.eclipse.ocl.examples.impactanalyzer.impl.OperationBodyToCallMapper;
import org.eclipse.ocl.examples.impactanalyzer.util.OCLFactory;
import org.eclipse.ocl.utilities.PredefinedType;


public class OperationCallExpTracer extends AbstractTracer<OperationCallExp> {
    private static final Set<String> sourcePassThroughStdLibOpNames;
    private static final Set<String> argumentPassThroughStdLibOpNames;
    static {
        sourcePassThroughStdLibOpNames = new HashSet<String>();
        sourcePassThroughStdLibOpNames.add(PredefinedType.ANY_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.AS_BAG_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.AS_SET_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.AS_ORDERED_SET_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.AS_SEQUENCE_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.AT_NAME);
        //	 sourcePassThroughStdLibOpNames.add(PredefinedType.ATRPRE_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.EXCLUDING_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.FIRST_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.FLATTEN_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.INCLUDING_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.INSERT_AT_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.APPEND_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.INTERSECTION_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.OCL_AS_TYPE_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.UNION_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.SELECT_BY_KIND_NAME);
        sourcePassThroughStdLibOpNames.add(PredefinedType.SELECT_BY_TYPE_NAME);

        argumentPassThroughStdLibOpNames = new HashSet<String>();
        argumentPassThroughStdLibOpNames.add(PredefinedType.INCLUDING_NAME);
        argumentPassThroughStdLibOpNames.add(PredefinedType.INSERT_AT_NAME);
        argumentPassThroughStdLibOpNames.add(PredefinedType.APPEND_NAME);
        argumentPassThroughStdLibOpNames.add(PredefinedType.UNION_NAME);
        // TODO what about "product"?
    }

    public OperationCallExpTracer(OperationCallExp expression, Stack<String> tuplePartNames, OCLFactory oclFactory) {
        super(expression, tuplePartNames, oclFactory);
    }

    @Override
    public NavigationStep traceback(EClass context, PathCache pathCache, OperationBodyToCallMapper operationBodyToCallMapper) {
        NavigationStep result;
        OCLExpression body = operationBodyToCallMapper.getOperationBody(getExpression().getReferredOperation());
        if (body != null) {
            // the operation body may lead to a recursion; to avoid a recursion we first create an
            // indirecting step here and insert it into the path cache so it will be found instead
            // of recurring
            IndirectingStep bodyStep = pathCache.createIndirectingStepFor(getExpression(), getTupleLiteralPartNamesToLookFor());
            // an OCL-specified operation; trace back using the body expression
            NavigationStep actualStep = pathCache.getOrCreateNavigationPath(body, context, operationBodyToCallMapper, getTupleLiteralPartNamesToLookFor(), oclFactory);
            bodyStep.setActualStep(actualStep);
            result = bodyStep;
        } else {
            String opName = getExpression().getReferredOperation().getName();
            if (opName.equals(PredefinedType.OCL_AS_TYPE_NAME)) {
                OCLExpression argument = (OCLExpression) (getExpression().getArgument()).get(0);
                if (argument instanceof TypeExp) {
                    EClassifier type = ((TypeExpImpl) argument).getReferredType();
                    IdentityNavigationStep identityStep = new IdentityNavigationStep((EClass) getExpression().getType(), (EClass) type,
                            getExpression());
                    NavigationStep sourceStep = pathCache.getOrCreateNavigationPath((OCLExpression) getExpression().getSource(),
                            context, operationBodyToCallMapper, getTupleLiteralPartNamesToLookFor(), oclFactory);
                    result = pathCache.navigationStepFromSequence(getExpression(), getTupleLiteralPartNamesToLookFor(), identityStep, sourceStep);
                } else {
                    throw new RuntimeException("What else could be the argument of oclAsType if not a TypeExp? "
                            + (argument.eClass()).getName());
                }
            } else if (sourcePassThroughStdLibOpNames.contains(opName)) {
                // FIXME handle product
                NavigationStep sourcePath = pathCache.getOrCreateNavigationPath((OCLExpression) getExpression()
                        .getSource(), context, operationBodyToCallMapper, getTupleLiteralPartNamesToLookFor(), oclFactory);
                if (argumentPassThroughStdLibOpNames.contains(opName)) {
                    int paramPos = 0;
                    if (opName.equals(PredefinedType.INSERT_AT_NAME)) {
                        // "insertAt" takes two arguments, the index and the object to add. 
                        // The OCL spec says the index comes first, so getting the first argument makes no sense in this case.
                        paramPos = 1;
                    }
                    OCLExpression argument = (OCLExpression) (getExpression().getArgument()).get(paramPos);
                    NavigationStep argumentPath = pathCache.getOrCreateNavigationPath(argument, context, operationBodyToCallMapper, getTupleLiteralPartNamesToLookFor(), oclFactory);
                    result = pathCache.navigationStepForBranch(
                            getInnermostElementType(getExpression().getType()),
                            context,
                            getExpression(),
                            getTupleLiteralPartNamesToLookFor(),
                            /* requireExactMatchForSourceType */ opName.equals(PredefinedType.SELECT_BY_TYPE_NAME),
                            sourcePath, argumentPath);
                } else {
                    result = pathCache.navigationStepForBranch(
                            getInnermostElementType(getExpression().getType()),
                            context,
                            getExpression(),
                            getTupleLiteralPartNamesToLookFor(),
                            /* requireExactMatchForSourceType */ opName.equals(PredefinedType.SELECT_BY_TYPE_NAME),
                            sourcePath);
                }
            } else if (opName.equals(PredefinedType.ALL_INSTANCES_NAME)) {
                // the object from where to trace back later in the navigate method may not
                // conform to the type on which allInstances() is invoked here; for example, the
                // expression may navigate from the result of allInstances() across an association
                // defined on a superclass of the one on which allInstances() was invoked. Therefore,
                // ensure that the typing of the AllInstancesNavigationStep is correct.
                EClass classifier = (EClass) ((TypeExp) getExpression().getSource())
                .getReferredType();
                result = new AllInstancesNavigationStep(classifier, context, getExpression(), pathCache.getOppositeEndFinder()); // non-absolute
            } else {
                result = new EmptyResultNavigationStep(getExpression()); 
                // hope, we didn't forget stdlib operations that pass on
                // source or argument values into their result
            }
        }
        applyScopesOnNavigationStep(result, operationBodyToCallMapper);
        return result;
    }
    
    @Override
    protected Set<Variable> calculateEnteringScope(OperationBodyToCallMapper operationBodyToCallMapper) {
        OCLExpression body = operationBodyToCallMapper.getOperationBody(getExpression().getReferredOperation());
        if (body != null){
            // an OCL-specified operation, the body creates a new scope
            return getVariablesScopedByExpression(body, operationBodyToCallMapper);
        }
        // standard OCL operations do not alter the scope as we cannot trace into their implementation
        return Collections.emptySet();
    }

    /**
     * When tracing into the called operation's body, all variables currently in scope are left.
     */
    @Override
    protected Set<Variable> calculateLeavingScopes(OperationBodyToCallMapper operationBodyToCallMapper) {
        return getAllVariablesInScope(getExpression(), operationBodyToCallMapper);
    }
}
