/*******************************************************************************
 * Copyright (c) 2008, 2014 Borland Software Corporation 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:
 *     Borland Software Corporation - initial API and implementation
 *     Christopher Gerking - bugs 388801, 358709, 427237, 431082
 *     Alex Paperno - bug 419299 
 *******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.evaluator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.m2m.internal.qvt.oml.ast.env.InternalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.ModelExtentContents;
import org.eclipse.m2m.internal.qvt.oml.ast.env.ModelParameterExtent;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEvaluationResult;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil;
import org.eclipse.m2m.internal.qvt.oml.expressions.DirectionKind;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.MappingParameter;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModelParameter;
import org.eclipse.m2m.internal.qvt.oml.expressions.OperationalTransformation;
import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter;
import org.eclipse.m2m.internal.qvt.oml.library.Context;
import org.eclipse.m2m.internal.qvt.oml.stdlib.DictionaryImpl;
import org.eclipse.m2m.internal.qvt.oml.stdlib.MutableListImpl;
import org.eclipse.m2m.internal.qvt.oml.stdlib.model.ExceptionInstance;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictionaryType;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ListType;
import org.eclipse.m2m.qvt.oml.util.Dictionary;
import org.eclipse.m2m.qvt.oml.util.IContext;
import org.eclipse.m2m.qvt.oml.util.ISessionData;
import org.eclipse.m2m.qvt.oml.util.MutableList;
import org.eclipse.m2m.qvt.oml.util.Utils;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.EvaluationEnvironment;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.types.CollectionType;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.types.TupleType;
import org.eclipse.ocl.util.CollectionUtil;

/**
 * @author dvorak
 */
public class EvaluationUtil {
	
	private EvaluationUtil() {
		super();
	}

	/**
	 * - Creates list of output resources (model extents) for each 'inout' and 'out' parameters of
	 *   transformation. For non-changed 'inout' model parameter corresponding resource is empty.
	 * @return ordered list of model extents
	 */
	public static QvtEvaluationResult createEvaluationResult(QvtOperationalEvaluationEnv mainEvalEnv) {
		TransformationInstance transfInstance = (TransformationInstance)mainEvalEnv.getValueOf(QvtOperationalEnv.THIS);		
		
		List<ModelExtentContents> extents = new ArrayList<ModelExtentContents>();		
		OperationalTransformation transformation = transfInstance.getTransformation();
		
		for(ModelParameter modelParam : transformation.getModelParameter()) {
			ModelInstance model = transfInstance.getModel(modelParam);
			ModelExtentContents contents = model.getExtent().getContents();
			if (modelParam.getKind() != DirectionKind.IN 
					&& modelParam.getEAnnotation(QvtOperationalParserUtil.QVT_AUTOGEN_MODELPARAM_EXPRESSION_URI) == null) {
	        	extents.add(contents);
			}			
		}
		
        List<Object> outParamValues = transformation.isIsBlackbox() ? Collections.emptyList() : makeOutParamValues(mainEvalEnv);
		
		ModelParameterExtent unboundExtent = mainEvalEnv.getAdapter(InternalEvaluationEnv.class).getUnboundExtent();
		return new QvtEvaluationResult(extents, unboundExtent.getRootObjects(), outParamValues);
	}
	
	private static List<Object> makeOutParamValues(QvtOperationalEvaluationEnv mainEvalEnv) {
		ImperativeOperation entryPoint = (ImperativeOperation) mainEvalEnv.getOperation();		
		List<Object> outParamValues = new ArrayList<Object>();
		
		for (EParameter param : mainEvalEnv.getOperation().getEParameters()) {
			MappingParameter mappingParam  = (MappingParameter) param;
// originally we took all non-IN?? why?			
			if (mappingParam.getKind() != DirectionKind.OUT) {
				continue;
			}
			Object valueOf = mainEvalEnv.getValueOf(mappingParam.getName());
			if (valueOf != null) {
				outParamValues.add(valueOf);
			}
		}
		for (VarParameter param : entryPoint.getResult()) {
			MappingParameter mappingParam  = (MappingParameter) param;
			if (mappingParam.getKind() == DirectionKind.IN) {
				continue;
			}
			
			Object valueOf = mainEvalEnv.getValueOf(mappingParam.getName());
			if (valueOf != null) {
				outParamValues.add(valueOf);
			}
		}
		return outParamValues;
	}

    static void mapOperationOutAndResultParams(QvtOperationalEvaluationEnv sourceEnv, QvtOperationalEvaluationEnv targetEnv) {
    	ImperativeOperation sourceOper = (ImperativeOperation)sourceEnv.getOperation();
    	ImperativeOperation targetOper = (ImperativeOperation)targetEnv.getOperation();
    	EList<? extends EParameter> sourceParams = sourceOper.getResult();
    	EList<? extends EParameter> targetParams = targetOper.getResult();
    	
    	if(sourceParams.size() != targetParams.size()) {
    		throw new IllegalArgumentException("Source/Target environment operations have incompatible signatures"); //$NON-NLS-1$
    	}

    	for (int i = 0; i < sourceParams.size(); i++) {
    		EParameter sourceParam = sourceParams.get(i);
    		EParameter targetParam = targetParams.get(i);
    		targetEnv.copyVariableValueFrom(sourceEnv, sourceParam.getName(), targetParam.getName());
		}
    	
    	if(sourceParams.size() > 1) {
    		// copy result variable explicitly as in case of many result parameters, there is no 'name=result' parameter 
    		targetEnv.copyVariableValueFrom(sourceEnv, Environment.RESULT_VARIABLE_NAME, Environment.RESULT_VARIABLE_NAME);
    	}

    	sourceParams = sourceOper.getEParameters();
    	targetParams = targetOper.getEParameters();
    	if(sourceParams.size() != targetParams.size()) {
    		throw new IllegalArgumentException("Source/Target environment operations have incompatible signatures"); //$NON-NLS-1$
    	}
    	
    	for (int i = 0; i < sourceParams.size(); i++) {
    		VarParameter sourceParam = (VarParameter) sourceParams.get(i);
    		if(sourceParam.getKind() == DirectionKind.OUT) {
    			EParameter targetParam = targetParams.get(i);
    			targetEnv.copyVariableValueFrom(sourceEnv, sourceParam.getName(), targetParam.getName());    			
    		}
		}
    }
    
    static Object formatLoggedElement(Object element) {
    	if(element instanceof ExceptionInstance) {
    		ExceptionInstance exception = (ExceptionInstance) element;    		
    		return exception.toString();
    	}
    	
    	return element;
    }
    
    static void checkCurrentStackDepth(QvtOperationalEvaluationEnv env) throws QvtStackOverFlowError {
		int depth = env.getDepth();
		if(depth >= QvtOperationalEvaluationEnv.MAX_STACK_DEPTH) {
			InternalEvaluationEnv iternEnv = env.getAdapter(InternalEvaluationEnv.class);
			iternEnv.throwQVTException(new QvtStackOverFlowError("Stack depth: " + depth)); //$NON-NLS-1$
		}    	
    }
    
	static List<ModelInstance> getTransfromationModelArguments(QvtOperationalEvaluationEnv rootEnvironment, OperationalTransformation transformation) throws IllegalArgumentException {
		List<Object> args = rootEnvironment.getOperationArgs();
		List<ModelInstance> transformArgs = new ArrayList<ModelInstance>(args.size());
		for (Object nextArg : args) {
			if(nextArg instanceof ModelInstance) {
				transformArgs.add((ModelInstance) nextArg);
			} else {
				throw new IllegalArgumentException(
					"transformation requires arguments of ModelInstance type"); //$NON-NLS-1$
			}
		}
		
		return transformArgs;
	}
	
	// TODO - this is a temp solution, consider this reference going into internal environment 
	static final ISessionData.Entry<QvtOperationalEvaluationEnv> AGGREGATING_ROOT_ENV = new ISessionData.SimpleEntry<QvtOperationalEvaluationEnv>(); 
	
	static Context createAggregatedContext(QvtOperationalEvaluationEnv evalEnv) {
		final IContext parentContext = evalEnv.getContext();
		
		Context nestedContext = new Context() {
			@Override
			protected ISessionData createSessionData() {
				return copySessionData();
			}
		};

		nestedContext.setLog(parentContext.getLog());
		nestedContext.setProgressMonitor(parentContext.getProgressMonitor());
		nestedContext.getSessionData().setValue(AGGREGATING_ROOT_ENV, evalEnv);

		return nestedContext;
	}
		
	public static QvtOperationalEvaluationEnv getAggregatingContext(QvtOperationalEvaluationEnv evalEnv) {
		return evalEnv.getContext().getSessionData().getValue(AGGREGATING_ROOT_ENV);
	}

	public static ImperativeOperation getOverridingOperation(QvtOperationalEvaluationEnv evalEnv, ImperativeOperation operation) {
        InternalEvaluationEnv internEvalEnv = evalEnv.getAdapter(InternalEvaluationEnv.class);
        assert internEvalEnv != null : "must adapt to internal env"; //$NON-NLS-1$
        
        ModuleInstance currentInternModule = internEvalEnv.getCurrentModule();
        // check if executed from transformation context (main() stack frame exists)
        if(currentInternModule != null) {
        	return currentInternModule.getAdapter(ModuleInstance.Internal.class).getOverridingOperation(operation);
        }
        
        return null;
	}
	
    public static <E> Collection<E> createNewCollectionOfSameKind(Collection<E> c) {
    	Collection<E> result;
    	
    	if (c instanceof MutableList<?>) {
    		result = new MutableListImpl<E>();
    	} else if (c instanceof Dictionary<?, ?>) {
    		result = new DictionaryImpl<Object, E>();
    	} else {
    		result = CollectionUtil.createNewCollectionOfSameKind(c);
    	}
    	
    	return result;
    }	
    
	public static <E> Collection<E> createNewCollection(CollectionType<EClassifier, EOperation> collectionType) {
		Collection<E> result = null;
		
		if (collectionType instanceof ListType) {
			result = Utils.createList();
		}
		else if (collectionType instanceof DictionaryType) {
			result = Utils.createDictionary();
		}
		else {
			CollectionKind kind = collectionType.getKind();
			if (kind != null && kind != CollectionKind.COLLECTION_LITERAL) {
				result = CollectionUtil.createNewCollection(collectionType.getKind());
			}
		}
		
		return result;
	}
	
	public static Object createInitialValue(EClassifier classifier, OCLStandardLibrary<EClassifier> oclstdlib,
			EvaluationEnvironment<EClassifier, EOperation, EStructuralFeature, EClass, EObject> evaluationEnv) {
		
		Object initialValue = null;
		
		if(classifier == oclstdlib.getString()) {
			initialValue = "";
		} else if(classifier == oclstdlib.getBoolean()) {
			initialValue = Boolean.FALSE;
		} else if(classifier == oclstdlib.getInteger()) {
			initialValue = Integer.valueOf(0);
		} else if(classifier == oclstdlib.getReal()) {
			initialValue = Double.valueOf(0);
		} else if(classifier == oclstdlib.getUnlimitedNatural()) {
			initialValue = Integer.valueOf(0);
		} else if(classifier instanceof CollectionType<?, ?>) {
			@SuppressWarnings("unchecked")
			CollectionType<EClassifier,EOperation> collType = (CollectionType<EClassifier,EOperation>) classifier;
			initialValue = createNewCollection(collType);
		}
		else if (classifier instanceof TupleType<?, ?>) {
			Map<EStructuralFeature, Object> propertyValues = new HashMap<EStructuralFeature, Object>();
			
			@SuppressWarnings("unchecked")
			TupleType<EOperation, EStructuralFeature> tupleType = (TupleType<EOperation, EStructuralFeature>) classifier;
			for (EStructuralFeature feature : tupleType.oclProperties()) {
				propertyValues.put(feature, createInitialValue(feature.getEType(), oclstdlib, evaluationEnv));
			}
			
			initialValue = evaluationEnv.createTuple(classifier, propertyValues);
		}
		
		return initialValue;
		
	}
	
	public static List<ETypedElement> getBlackboxSignature(OperationalTransformation transformation) {
		
		List<ETypedElement> signatureTypedElements = new ArrayList<ETypedElement>();
		
		signatureTypedElements.addAll(transformation.getModelParameter());
		signatureTypedElements.addAll(transformation.getConfigProperty());
		
		return signatureTypedElements;
		
	}
    
}
