/*******************************************************************************
 * Copyright (c) 2016, 2018 Willink Transformations 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 - initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.pivot.qvtrelation.utilities;

import java.util.List;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.QVTbaseFactory;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseHelper;
import org.eclipse.qvtd.pivot.qvtbase.utilities.TraceHelper;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.QVTrelationFactory;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp;
import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
import org.eclipse.qvtd.pivot.qvtrelation.SharedVariable;
import org.eclipse.qvtd.pivot.qvtrelation.TemplateVariable;
import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.QVTtemplateFactory;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
import com.google.common.collect.Iterables;

/**
 * QVTrelationHelper provides helper routines to assist creation of QVTrelation model elements.
 */
public class QVTrelationHelper extends QVTbaseHelper
{
	public QVTrelationHelper(@NonNull EnvironmentFactory environmentFactory) {
		super(environmentFactory);
	}

	public void addWhenPredicate(@NonNull Relation qvtrRelation, @NonNull OCLExpression asExpression) {
		Pattern asPattern = qvtrRelation.getWhen();
		if (asPattern == null) {
			asPattern = QVTbaseFactory.eINSTANCE.createPattern();
			qvtrRelation.setWhen(asPattern);
		}
		asPattern.getPredicate().add(createPredicate(asExpression));
	}

	public void addWherePredicate(@NonNull Relation qvtrRelation, @NonNull OCLExpression asExpression) {
		Pattern asPattern = qvtrRelation.getWhere();
		if (asPattern == null) {
			asPattern = QVTbaseFactory.eINSTANCE.createPattern();
			qvtrRelation.setWhere(asPattern);
		}
		asPattern.getPredicate().add(createPredicate(asExpression));
	}

	/**
	 * Traverse the templateExp hierarchy assigning all special variables (_) to specialVariables allocating a distinctive name to each.
	 * Append special member variables to relationVariables as well.
	 */
	public void computeBoundVariables(@NonNull List<@NonNull Variable> boundVariables, @NonNull OCLExpression asExpression) {
		if (asExpression instanceof ObjectTemplateExp) {
			ObjectTemplateExp asObjectTemplateExp = (ObjectTemplateExp)asExpression;
			Variable asBoundVariable = QVTrelationUtil.getBindsTo(asObjectTemplateExp);
			if (!boundVariables.contains(asBoundVariable)) {
				boundVariables.add(asBoundVariable);
			}
			for (@NonNull PropertyTemplateItem asPart : QVTrelationUtil.getOwnedParts(asObjectTemplateExp)) {
				computeBoundVariables(boundVariables, QVTrelationUtil.getOwnedValue(asPart));
			}
		}
		else if (asExpression instanceof CollectionTemplateExp) {
			CollectionTemplateExp asCollectionTemplateExp = (CollectionTemplateExp)asExpression;
			Variable asBoundVariable = QVTrelationUtil.getBindsTo(asCollectionTemplateExp);
			if (!boundVariables.contains(asBoundVariable)) {
				boundVariables.add(asBoundVariable);
			}
			for (@NonNull OCLExpression asMemberExpression : QVTrelationUtil.getOwnedMembers(asCollectionTemplateExp)) {
				computeBoundVariables(boundVariables, asMemberExpression);
			}
		}
		//		else if (asExpression instanceof VariableExp) {			// FIXME temporary test compatibility
		//			Variable asVariable = QVTrelationUtil.getReferredVariable((VariableExp)asExpression);
		//			if (!boundVariables.contains(asVariable)) {
		//				boundVariables.add(asVariable);
		//			}
		//		}
	}

	public @NonNull CollectionTemplateExp createCollectionTemplateExp(@NonNull TemplateVariable asTemplateVariable, org.eclipse.ocl.pivot.@NonNull Class asClass, boolean isRequired) {
		CollectionTemplateExp asCollectionTemplateExp = QVTtemplateFactory.eINSTANCE.createCollectionTemplateExp();
		//		asObjectTemplateExp.setName(PivotUtil.getName(asTemplateVariable));
		asCollectionTemplateExp.setType(asClass);
		asCollectionTemplateExp.setReferredCollectionType((CollectionType)asClass);
		asCollectionTemplateExp.setIsRequired(isRequired);
		asCollectionTemplateExp.setBindsTo(asTemplateVariable);
		return asCollectionTemplateExp;
	}

	public @NonNull DomainPattern createDomainPattern(@NonNull TemplateExp asTemplateExp) {
		DomainPattern asDomainPattern = QVTrelationFactory.eINSTANCE.createDomainPattern();
		asDomainPattern.setTemplateExpression(asTemplateExp);
		return asDomainPattern;
	}

	public @NonNull Key createKey(org.eclipse.ocl.pivot.@NonNull Class asClass, @NonNull Iterable<@NonNull Property> asProperties) {
		Key asKey = QVTrelationFactory.eINSTANCE.createKey();
		asKey.setIdentifies(asClass);
		Iterables.addAll(QVTrelationUtil.Internal.getOwnedPartsList(asKey), asProperties);
		return asKey;
	}

	public @NonNull ObjectTemplateExp createObjectTemplateExp(@NonNull TemplateVariable asTemplateVariable, org.eclipse.ocl.pivot.@NonNull Class asClass, boolean isRequired) {
		ObjectTemplateExp asObjectTemplateExp = QVTtemplateFactory.eINSTANCE.createObjectTemplateExp();
		//		asObjectTemplateExp.setName(PivotUtil.getName(asTemplateVariable));
		setType(asObjectTemplateExp, asClass,isRequired);
		asObjectTemplateExp.setReferredClass(asClass);
		asObjectTemplateExp.setBindsTo(asTemplateVariable);
		return asObjectTemplateExp;
	}

	public @NonNull PropertyTemplateItem createPropertyTemplateItem(@NonNull Property asProperty, @NonNull OCLExpression asExpression) {
		PropertyTemplateItem asPropertyTemplateItem = QVTtemplateFactory.eINSTANCE.createPropertyTemplateItem();
		boolean isOpposite = asProperty.isIsImplicit();
		asPropertyTemplateItem.setIsOpposite(isOpposite);
		asPropertyTemplateItem.setReferredProperty(isOpposite ? PivotUtil.getOpposite(asProperty) : asProperty);
		asPropertyTemplateItem.setValue(asExpression);
		return asPropertyTemplateItem;
	}

	public @NonNull Relation createRelation(@NonNull String name, @NonNull Iterable<@NonNull RelationDomain> asRelationDomains) {
		Relation asRelation = QVTrelationFactory.eINSTANCE.createRelation();
		asRelation.setName(name);
		Iterables.addAll(QVTrelationUtil.Internal.getOwnedDomainsList(asRelation), asRelationDomains);
		return asRelation;
	}

	public @NonNull RelationCallExp createRelationCallExp(@NonNull Relation asRelation, @NonNull List<? extends @NonNull OCLExpression> asArguments) {
		RelationCallExp asRelationCallExp = QVTrelationFactory.eINSTANCE.createRelationCallExp();
		asRelationCallExp.setReferredRelation(asRelation);
		Iterables.addAll(QVTrelationUtil.Internal.getOwnedArgumentsList(asRelationCallExp), asArguments);
		setType(asRelationCallExp, environmentFactory.getStandardLibrary().getBooleanType(), true);;
		return asRelationCallExp;
	}

	public @NonNull RelationDomain createRelationDomain(@NonNull TypedModel asTypedModel) {
		RelationDomain asRelationDomain = QVTrelationFactory.eINSTANCE.createRelationDomain();
		asRelationDomain.setTypedModel(asTypedModel);
		return asRelationDomain;
	}

	public @NonNull RelationalTransformation createRelationalTransformation(@NonNull String name, @NonNull Iterable<@NonNull TypedModel> asTypedModels) {
		StandardLibrary standardLibrary = environmentFactory.getStandardLibrary();
		RelationalTransformation asRelationalTransformation = QVTrelationFactory.eINSTANCE.createRelationalTransformation();
		asRelationalTransformation.setName(name);
		Iterables.addAll(QVTrelationUtil.Internal.getModelParameterList(asRelationalTransformation), asTypedModels);
		asRelationalTransformation.getSuperClasses().add(standardLibrary.getOclElementType());
		return asRelationalTransformation;
	}

	public @NonNull SharedVariable createSharedVariable(@Nullable String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) {
		SharedVariable asVariable = QVTrelationFactory.eINSTANCE.createSharedVariable();
		asVariable.setName(name);
		asVariable.setIsImplicit(name == null);
		setType(asVariable, asType, isRequired);
		asVariable.setOwnedInit(asInitExpression);
		return asVariable;
	}

	public @NonNull TemplateVariable createTemplateVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) {
		TemplateVariable asVariable = QVTrelationFactory.eINSTANCE.createTemplateVariable();
		asVariable.setName(name);
		setType(asVariable, asType, isRequired);
		asVariable.setOwnedInit(asInitExpression);
		return asVariable;
	}

	public @NonNull Variable createTraceClassVariable(@NonNull TraceHelper traceHelper) {
		SharedVariable traceClassVariable;
		traceClassVariable = QVTrelationFactory.eINSTANCE.createSharedVariable();
		traceClassVariable.setName(QVTrelationUtil.TRACE_CLASS_NAME);
		traceClassVariable.setIsImplicit(true);
		setType(traceClassVariable, traceHelper.getTraceElementClass(), true);		// Use an ancestral QVTTrace type since derived type not yet synthesized
		traceClassVariable.setOwnedInit(null);
		return traceClassVariable;
	}

	public @NonNull TypedModel createTraceTypedModel() {
		TypedModel asTypedModel = QVTbaseFactory.eINSTANCE.createTypedModel();
		asTypedModel.setName(QVTrelationUtil.TRACE_TYPED_MODEL_NAME);
		asTypedModel.setIsTrace(true);
		return asTypedModel;
	}
}