/*******************************************************************************
 * Copyright (c) 2015 Willink Transformations 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:
 *     E.D.Willink - initial API and implementation
 ******************************************************************************/
package org.eclipse.qvtd.pivot.qvtimperative.evaluation;

import java.io.IOException;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.pivot.ids.CollectionTypeId;
import org.eclipse.ocl.pivot.internal.complete.StandardLibraryInternal;
import org.eclipse.ocl.pivot.internal.evaluation.AbstractExecutor;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.CollectionValue;
import org.eclipse.ocl.pivot.values.InvalidValueException;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.Rule;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcorebase.Area;
import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcorebase.EnforcementOperation;
import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtcorebase.VariableAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
import org.eclipse.qvtd.pivot.qvtimperative.ConnectionVariable;
import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCall;
import org.eclipse.qvtd.pivot.qvtimperative.MappingStatement;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.InvocationFailedException;

public class BasicQVTiExecutor extends AbstractExecutor implements QVTiExecutor
{
    protected final @NonNull Transformation transformation;
    private @Nullable QVTiTransformationAnalysis transformationAnalysis = null;
    private @Nullable QVTiModelManager modelManager = null;

    public BasicQVTiExecutor(@NonNull QVTiEnvironmentFactory environmentFactory, @NonNull Transformation transformation) {
		super(environmentFactory);
		this.transformation = transformation;
	}

	/**
	 * Adds the model.
	 */
	public void addModel(@NonNull TypedModel typedModel, @NonNull Resource resource) {
		getModelManager().addModel(typedModel, resource);
	}

	@Override
	protected EvaluationVisitor.@NonNull EvaluationVisitorExtension createEvaluationVisitor() {
		IQVTiEvaluationVisitor visitor = new QVTiEvaluationVisitor(this);
	    if (environmentFactory.isEvaluationTracingEnabled()) {
	        // decorate the evaluation visitor with tracing support
	        visitor = new QVTiTracingEvaluationVisitor(visitor);
//	        ((QVTiTracingEvaluationVisitor)visitor).setVerboseLevel(QVTiTracingEvaluationVisitor.VERBOSE_LEVEL_HIGH);
	    }
		return visitor;
	}

    @Override
	public void createModel(@NonNull String name, @NonNull URI modelURI, @Nullable String contentType) {
        TypedModel typedModel = NameUtil.getNameable(transformation.getModelParameter(), name);
        if (typedModel == null) {
        	throw new IllegalStateException("Unknown TypedModel '" + name + "'");
        }
        Resource resource = environmentFactory.getResourceSet().createResource(modelURI, contentType);
        if (resource != null) {
        	getModelManager().addModel(typedModel, resource);
        }
    }

	@Override
	protected EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension createNestedEvaluationEnvironment(EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension evaluationEnvironment, @NonNull NamedElement executableObject, @Nullable OCLExpression callingObject) {
		if (evaluationEnvironment instanceof QVTiEvaluationEnvironment) {
			return new QVTiNestedEvaluationEnvironment((QVTiEvaluationEnvironment) evaluationEnvironment, executableObject, callingObject);
		}
		else{
			return super.createNestedEvaluationEnvironment(evaluationEnvironment, executableObject, callingObject);
		}
	}

	@Override
	protected EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension createRootEvaluationEnvironment(@NonNull NamedElement executableObject) {
		if (executableObject instanceof Transformation) {
			return new QVTiRootEvaluationEnvironment(this, (Transformation) executableObject);
		}
		else {
			return super.createRootEvaluationEnvironment(executableObject);
		}
	}
	
	@Override	
	public void dispose() {
		if (modelManager != null) {
			modelManager.dispose();
		}
		super.dispose();
	}

	protected void doCommits(@NonNull Mapping mapping, @NonNull EvaluationVisitor undecoratedVisitor) {
		//
		//	creations
		//
		for (Domain domain : mapping.getDomain()) {
			if (domain.isIsEnforceable()) {
				CoreDomain enforceableDomain = (CoreDomain)domain;
				BottomPattern enforceableBottomPattern = enforceableDomain.getBottomPattern();
				for (RealizedVariable realizedVariable : enforceableBottomPattern.getRealizedVariable()) {
					OCLExpression ownedInit = realizedVariable.getOwnedInit();
					if (ownedInit != null) {
						Object initValue = ownedInit.accept(undecoratedVisitor);
						getEvaluationEnvironment().add(realizedVariable, initValue);
				        replace(realizedVariable, initValue);
				        Area area = ((BottomPattern)realizedVariable.eContainer()).getArea();
				        TypedModel typedModel = QVTcoreBaseUtil.getTypedModel(area);
				        assert typedModel != null;
						Object ecoreValue = getIdResolver().ecoreValueOf(null, initValue);
						assert ecoreValue != null;
				        getModelManager().addModelElement(typedModel, ecoreValue);
					}
				}
				for (RealizedVariable realizedVariable : enforceableBottomPattern.getRealizedVariable()) {
					if (realizedVariable.getOwnedInit() == null) {
						realizedVariable.accept(undecoratedVisitor);
					}
				}
			}
		}
		//
        // property and connection assignments
		//
		BottomPattern middleBottomPattern = mapping.getBottomPattern();
		for (Assignment assignment : middleBottomPattern.getAssignment()) {
			if (!(assignment instanceof VariableAssignment)) {
				assignment.accept(undecoratedVisitor);
			}
		}
		//
        // enforcement operations
		//
		for (Domain domain : mapping.getDomain()) {
			if (domain.isIsEnforceable()) {
				CoreDomain enforceableDomain = (CoreDomain)domain;
				BottomPattern enforceableBottomPattern = enforceableDomain.getBottomPattern();
				for (EnforcementOperation enforceOp : enforceableBottomPattern.getEnforcementOperation()) {
					enforceOp.accept(undecoratedVisitor);
				}
			}
		}
//		for (EnforcementOperation enforceOp : middleBottomPattern.getEnforcementOperation()) {
//			enforceOp.accept(undecoratedVisitor);
//		}
	}

	protected boolean doPredicatesAndEvaluations(@NonNull Mapping mapping, @NonNull EvaluationVisitor undecoratedVisitor) {
		//
        // middle guard predicates
		//
		GuardPattern middleGuardPattern = mapping.getGuardPattern();
//		assert middleGuardPattern.getVariable().isEmpty();		middle guards are connection variables
		for (@NonNull Predicate predicate : ClassUtil.nullFree(middleGuardPattern.getPredicate())) {
			// If the predicate is not true, the binding is not valid
			Object result = predicate.accept(undecoratedVisitor);
			if (result != Boolean.TRUE) {
				return false;
			}
		}
		for (@NonNull Domain domain : ClassUtil.nullFree(mapping.getDomain())) {
			if (!domain.isIsEnforceable()) {
				CoreDomain checkableDomain = (CoreDomain)domain;
				GuardPattern checkableGuardPattern = checkableDomain.getGuardPattern();
				assert checkableGuardPattern.getPredicate().isEmpty();
				BottomPattern checkableBottomPattern = checkableDomain.getBottomPattern();
				assert checkableBottomPattern.getAssignment().isEmpty();
				assert checkableBottomPattern.getEnforcementOperation().isEmpty();
				assert checkableBottomPattern.getPredicate().isEmpty();
				assert checkableBottomPattern.getRealizedVariable().isEmpty();
//				assert checkableBottomPattern.getVariable().isEmpty();
				for (@NonNull Variable rVar : ClassUtil.nullFree(checkableBottomPattern.getVariable())) {
					OCLExpression ownedInit = rVar.getOwnedInit();
					assert ownedInit == null;
				}
			}
			else {
				CoreDomain enforceableDomain = (CoreDomain)domain;
				GuardPattern enforceableGuardPattern = enforceableDomain.getGuardPattern();
				assert enforceableGuardPattern.getPredicate().isEmpty();
				BottomPattern enforceableBottomPattern = enforceableDomain.getBottomPattern();
				assert enforceableBottomPattern.getAssignment().isEmpty();
				assert enforceableBottomPattern.getPredicate().isEmpty();
				for (@NonNull Variable rVar : ClassUtil.nullFree(enforceableBottomPattern.getVariable())) {
					OCLExpression ownedInit = rVar.getOwnedInit();
					if (ownedInit != null) {
						Object initValue = ownedInit.accept(undecoratedVisitor);
						replace(rVar, initValue);
					}
				}
			}
		}
		BottomPattern middleBottomPattern = mapping.getBottomPattern();
		assert middleBottomPattern.getEnforcementOperation().isEmpty();
		assert middleBottomPattern.getRealizedVariable().isEmpty();
		//
        // variable declarations/initializations
		//
		for (@NonNull Variable rVar : ClassUtil.nullFree(middleBottomPattern.getVariable())) {
			if (rVar instanceof ConnectionVariable) {
				CollectionValue.Accumulator accumulator = ValueUtil.createCollectionAccumulatorValue((CollectionTypeId) rVar.getTypeId());
				OCLExpression ownedInit = rVar.getOwnedInit();
				if (ownedInit != null) {
					Object initValue = ownedInit.accept(undecoratedVisitor);
					accumulator = ValueUtil.createCollectionAccumulatorValue((CollectionTypeId) ownedInit.getTypeId());
					if (initValue != null) {
						for (Object value : (Iterable<?>)initValue) {
							accumulator.add(value);
						}
					}
				}
				else {
					accumulator = ValueUtil.createCollectionAccumulatorValue((CollectionTypeId) rVar.getTypeId());
				}
				replace(rVar, accumulator);
			}
			else {
				OCLExpression ownedInit = rVar.getOwnedInit();
				if (ownedInit != null) {
					Object initValue = ownedInit.accept(undecoratedVisitor);
					replace(rVar, initValue);
				}
			}
		}
		//
        // variable assignments
		//
		for (@NonNull Assignment assignment : ClassUtil.nullFree(middleBottomPattern.getAssignment())) {
			if (assignment instanceof VariableAssignment) {
				assignment.accept(undecoratedVisitor);
			}
		}
		//
        // middle bottom predicates
		//
		for (@NonNull Predicate predicate : ClassUtil.nullFree(middleBottomPattern.getPredicate())) {
			// If the predicate is not true, the binding is not valid
			Object result = predicate.accept(undecoratedVisitor);
			if (result != Boolean.TRUE) {
				return false;
			}
		}
		return true;
	}

	@Override
	public Boolean execute() {
		initializeEvaluationEnvironment(transformation);
		getRootEvaluationEnvironment();
        StandardLibraryInternal standardLibrary = environmentFactory.getStandardLibrary();
		Variable ownedContext = QVTbaseUtil.getContextVariable(standardLibrary, transformation);
		QVTiModelManager modelManager = getModelManager();
		add(ownedContext, modelManager.getTransformationInstance(transformation));
        for (TypedModel typedModel : transformation.getModelParameter()) {
        	if (typedModel != null) {
	            ownedContext = QVTbaseUtil.getContextVariable(standardLibrary, typedModel);
	            add(ownedContext, modelManager.getTypedModelInstance(typedModel));
        	}
        }
        return executeInternal();
	}

	protected Boolean executeInternal() {
		return (Boolean) getEvaluationVisitor().visit(transformation);
	}

	@Override
	public @NonNull QVTiEnvironmentFactory getEnvironmentFactory() {
		return (QVTiEnvironmentFactory) super.getEnvironmentFactory();
	}

	@Override
	public @NonNull QVTiEvaluationEnvironment getEvaluationEnvironment() {
		return (QVTiEvaluationEnvironment) super.getEvaluationEnvironment();
	}

	/**
	 * Gets the named TypedModel.
	 */
	@Override
	public @Nullable Resource getModel(@NonNull String name) {
        TypedModel typedModel = NameUtil.getNameable(transformation.getModelParameter(), name);
        if (typedModel == null) {
        	throw new IllegalStateException("Unknown TypedModel '" + name + "'");
        }
        return getModelManager().getModel(typedModel);
    }
	
	@Override
	public @NonNull QVTiModelManager getModelManager() {
		QVTiModelManager modelManager2 = modelManager;
		if (modelManager2 == null) {
			modelManager = modelManager2 = new QVTiModelManager(getTransformationAnalysis());
		}
		return modelManager2;
	}

	public @NonNull Transformation getTransformation() {
		return transformation;
	}
	
	public @NonNull QVTiTransformationAnalysis getTransformationAnalysis() {
		QVTiTransformationAnalysis transformationAnalysis2 = transformationAnalysis;
		if (transformationAnalysis2 == null) {
			transformationAnalysis = transformationAnalysis2 = getEnvironmentFactory().createTransformationAnalysis();
			transformationAnalysis2.analyzeTransformation(transformation);
		}
		return transformationAnalysis2;
	}

	@Override
	public @Nullable Object internalExecuteMappingCall(@NonNull MappingCall mappingCall, @NonNull Map<Variable, Object> variable2value, @NonNull EvaluationVisitor undecoratedVisitor) {
		Mapping calledMapping = mappingCall.getReferredMapping();
		if (calledMapping != null) {
			pushEvaluationEnvironment(calledMapping, mappingCall);
			try {
				for (Map.Entry<Variable,Object> entry : variable2value.entrySet()) {
					@SuppressWarnings("null")@NonNull Variable variable = entry.getKey();
					replace(variable, entry.getValue());
				}
				calledMapping.accept(undecoratedVisitor);
			}
			finally {
				popEvaluationEnvironment();
			}
		}
    	return true;
	}

	@Override
	public @Nullable Object internalExecuteMapping(@NonNull Mapping mapping, @NonNull EvaluationVisitor undecoratedVisitor) {
		try {
			//
			//	Check the predicates
			//
			if (!doPredicatesAndEvaluations(mapping, undecoratedVisitor)) {
				return false;
			}
		}
		catch (InvocationFailedException e) {
			throw e;
		}
		catch (Throwable e) {
			// Mapping failure are just mappings that never happened.
	    	AbstractTransformer.EXCEPTIONS.println("Execution failure in " + mapping.getName() + " : " + e);
	    	return false;
		}
		//
		//	Perform the instance model addition and property assignment only after all expressions have been evaluated
		//	possibly throwing a not-ready exception that bypasses premature commits.
		//
		doCommits(mapping, undecoratedVisitor);
		//
		//	Invoke any corrolaries
		//
 		MappingStatement mappingStatement = mapping.getMappingStatement();
		if (mappingStatement != null) {
			mappingStatement.accept(undecoratedVisitor);
		}
        return true;
	}
	
	@Override
	public void internalExecuteNavigationAssignment(@NonNull NavigationAssignment navigationAssignment, @NonNull Object slotObject, @Nullable Object ecoreValue, @Nullable Object childKey) {
		Property targetProperty = QVTcoreBaseUtil.getTargetProperty(navigationAssignment);
		targetProperty.initValue(slotObject, ecoreValue);
    	QVTiModelManager modelManager = getModelManager();
		Integer cacheIndex = modelManager.getTransformationAnalysis().getCacheIndex(navigationAssignment);
		if (cacheIndex != null) {
			modelManager.setUnnavigableOpposite(cacheIndex, slotObject, ecoreValue);
		}
	}

	@Override
	public @Nullable Object internalExecuteRealizedVariable(@NonNull RealizedVariable realizedVariable, @NonNull EvaluationVisitor undecoratedVisitor) {
        // Realized variables are in the mapping's target bottom pattern
        // and create elements in the target model. The realized variables
        // are being visited for each binding of variable in the mapping. 
        Type type = realizedVariable.getType();
        if (!(type instanceof org.eclipse.ocl.pivot.Class)) {
        	return null;
        }
        Area area = ((BottomPattern)realizedVariable.eContainer()).getArea();
        TypedModel typedModel = QVTcoreBaseUtil.getTypedModel(area);
        assert typedModel != null;
		Object element = ((org.eclipse.ocl.pivot.Class)type).createInstance();
        // Add the realize variable binding to the environment
        replace(realizedVariable, element);
        getModelManager().addModelElement(typedModel, element);
        return element;
	}

	@Override
	public @Nullable Object internalExecuteTransformation(@NonNull Transformation transformation, @NonNull EvaluationVisitor undecoratedVisitor) {
        Rule rule = NameUtil.getNameable(transformation.getRule(), QVTimperativeUtil.ROOT_MAPPING_NAME);
        if (rule == null) {
        	throw new IllegalStateException("Transformation " + transformation.getName() + " has no root mapping");
        }
        CallExp callExp = PivotFactory.eINSTANCE.createOperationCallExp();		// FIXME TransformationCallExp
        pushEvaluationEnvironment(rule, callExp);
        try {
        	rule.accept(undecoratedVisitor);
        }
        finally {
        	popEvaluationEnvironment();
        }
        return true;
	}

	/**
	 * Loads the modelURI and binds it to the named TypedModel.
	 */
	public void loadModel(@NonNull String name, @NonNull URI modelURI) {
        TypedModel typedModel = NameUtil.getNameable(transformation.getModelParameter(), name);
        if (typedModel == null) {
        	throw new IllegalStateException("Unknown TypedModel '" + name + "'");
        }
        Resource resource = environmentFactory.getResourceSet().getResource(modelURI, true);
        if (resource != null) {
        	getModelManager().addModel(typedModel, resource);
        }
    }

	@Override
	public void loadModel(@NonNull String name, @NonNull URI modelURI, @Nullable String contentType) {
        TypedModel typedModel = NameUtil.getNameable(transformation.getModelParameter(), name);
        if (typedModel == null) {
        	throw new IllegalStateException("Unknown TypedModel '" + name + "'");
        }
        Resource resource;
        ResourceSet resourceSet = environmentFactory.getResourceSet();
		if (contentType == null) {
        	resource = resourceSet.getResource(modelURI, true);
        }
        else {
        	resource = resourceSet.createResource(modelURI, contentType);
        	try {
				resource.load(null);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
        if (resource != null) {
        	getModelManager().addModel(typedModel, resource);
        }
    }

    @Override
	public void replace(@NonNull TypedElement asVariable, @Nullable Object value) {
		if (value == null) {
			if (asVariable.isIsRequired()) {
				throw new InvalidValueException("Attempted to assign null value to " + asVariable);
			}
		}
		else if (!(value instanceof Throwable)){
			Type valueType = getIdResolver().getDynamicTypeOf(value);
			Type variableType = ClassUtil.nonNullState(asVariable.getType());
			if (!valueType.conformsTo(getStandardLibrary(), variableType) && (variableType.getESObject() != EcorePackage.Literals.EOBJECT)) {	// FIXME EObject fudge for Adolfo's test models
				throw new InvalidValueException("Attempted to assign incompatible value to " + asVariable);
			}
		}
		super.replace(asVariable, value);
	}

	public Resource saveModel(@NonNull String name, @NonNull URI modelURI, String contentType, @Nullable Map<?, ?> savingOptions) throws IOException {
        TypedModel typedModel = NameUtil.getNameable(transformation.getModelParameter(), name);
        if (typedModel == null) {
        	throw new IllegalStateException("Unknown TypedModel '" + name + "'");
        }
    	Resource resource = getModelManager().getModel(typedModel);
        if (resource == null) {
        	resource = environmentFactory.getResourceSet().createResource(modelURI, contentType);
        }
        if (resource != null) {
        	resource.save(savingOptions);
        }
        return resource;
    }

	@Override
	public void saveModels() {
		getModelManager().saveModels();
	}
	
	public void saveModels(@Nullable Map<?, ?> savingOptions) {
		getModelManager().saveModels(savingOptions);
	}
	
	public void saveModels(@NonNull URI traceURI) {
		this.saveModels(traceURI, null);
	}
	
	public void saveModels(@NonNull URI traceURI, @Nullable Map<?, ?> savingOptions) {
		this.saveModels(savingOptions);
		getModelManager().saveMiddleModel(traceURI, savingOptions);
	}

	public void saveTransformation(Map<?,?> options) throws IOException {
    	XMLResource resource = (XMLResource) transformation.eResource();
//    	new AS2ID().assignIds(resource.getResourceSet());
		resource.save(options);
	}
}
