/*******************************************************************************
 * Copyright (c) 2015 Willink Transformations, University of York 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:
 *     Adolfo Sanchez-Barbudo Herrera (University of York) - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.examples.autogen.xtend

import java.util.ArrayList
import java.util.List
import org.eclipse.emf.codegen.ecore.genmodel.GenClassifier
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.mwe.core.issues.Issues
import org.eclipse.ocl.examples.codegen.generator.AbstractGenModelHelper
import org.eclipse.ocl.examples.codegen.generator.GenModelHelper
import org.eclipse.ocl.pivot.Class
import org.eclipse.ocl.pivot.Operation
import org.eclipse.ocl.pivot.Type
import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal
import org.eclipse.ocl.pivot.utilities.ClassUtil
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory
import org.eclipse.ocl.pivot.CollectionType
import org.eclipse.ocl.pivot.utilities.OCL
import org.eclipse.ocl.examples.build.utilities.GenPackageHelper
import org.eclipse.ocl.examples.autogen.lookup.LookupCodeGenerator
import org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup
import org.eclipse.ocl.pivot.model.OCLstdlib
import java.util.Set
import org.eclipse.ocl.examples.autogen.lookup.LookupCGUtil
import org.eclipse.ocl.examples.build.xtend.GenerateVisitorsXtend
import org.eclipse.ocl.examples.build.xtend.MergeWriter

class GenerateAutoLookupInfrastructureXtend extends GenerateVisitorsXtend
{

	protected String lookupFilePath;
	// FIXME The lookupVisitor will be in the normal visitors folder, but all the artifacts generated by this component
	// will be in a different one
	protected String lookupArtifactsJavaPackage;
	protected String lookupArtifactsOutputFolder;
	protected String lookupPackageName;
	protected String superLookupPackageName
	protected String baseLookupPackageName
	protected GenModelHelper genModelHelper;
	
	override checkConfiguration(Issues issues) {
		super.checkConfiguration(issues);
		if (!isDefined(lookupFilePath)) {
			issues.addError(this, "lookupFilePath must be specified");
		}
	}

	/**
	 * The path inside the projectName to the Complete OCL file which contains the 
	 * name resolution description (e.g. "model/NameResolution.ocl"). It 
	 * can't be null
	 */
	def setLookupFilePath(String lookupFilePath) {
		this.lookupFilePath = lookupFilePath;
	}
	
	def setLookupPackageName(String lookupPackageName) {
		this.lookupPackageName = lookupPackageName;
	}
	
	def setSuperLookupPackageName(String superLookupPackageName) {
		this.superLookupPackageName = superLookupPackageName;
	}
	
	def setBaseLookupPackageName(String baseLookupPackageName) {
		this.baseLookupPackageName = baseLookupPackageName;
	}
	
	protected override doSetup() {
		CompleteOCLStandaloneSetup.doSetup();
		OCLstdlib.install();
	}
	

	override protected doPropertiesConfiguration(OCL ocl) {
		super.doPropertiesConfiguration(ocl);
		val genModelURI = getGenModelURI(projectName, genModelFile);
		val genModelResource = getGenModelResource(ocl, genModelURI);
		val genPackage = getGenPackage(genModelResource);
		
		var helper = new GenPackageHelper(genPackage);
		if (!lookupPackageName.isDefined || lookupPackageName.length == 0) {
			lookupPackageName = helper.modelPackageName + ".lookup"	
		}
		 
		if (isDerived()) {
			val superGenModelURI = getGenModelURI(superProjectName, superGenModelFile);
			val superGenModelResource = getGenModelResource(ocl, superGenModelURI);
			val superGenPackage = getGenPackage(superGenModelResource);
			helper = new GenPackageHelper(superGenPackage)
			if (!superLookupPackageName.isDefined || superLookupPackageName.length == 0) {
				superLookupPackageName = helper.modelPackageName + ".lookup"
			}
			
			val baseGenModelURI = getGenModelURI(baseProjectName, baseGenModelFile);
			val baseGenModelResource = getGenModelResource(ocl, baseGenModelURI);
			val baseGenPackage = getGenPackage(baseGenModelResource);
			helper = new GenPackageHelper(baseGenPackage);
			if (!baseLookupPackageName.isDefined || baseLookupPackageName.length == 0) {
				baseLookupPackageName = helper.modelPackageName + ".lookup"
			}
		} else {
			if (!baseLookupPackageName.isDefined || baseLookupPackageName.length == 0) {
				baseLookupPackageName = lookupPackageName;
			}
		}
	}
	
	@SuppressWarnings("null")
	protected def doGenerateVisitors(/*@NonNull*/ GenPackage genPackage) {
		LookupCodeGenerator.generate(genPackage, superGenPackage, baseGenPackage, projectName, lookupFilePath,
				lookupPackageName, lookupPackageName,null); // FIXME
	}
	
	protected def void generateAutoLookupResultItf(/*@NonNull*/ EPackage ePackage) {
		var boolean isDerived = isDerived();
		if (!isDerived) {
			var MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + projectPrefix + "LookupResult.java");
			writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»
	
	import java.util.List;
	
	import org.eclipse.jdt.annotation.NonNull;
	import org.eclipse.jdt.annotation.Nullable;
	
	/**
	 * The lookup result returned by the name lookup solver
	 */
	public interface «projectPrefix»LookupResult<NE> {
	
		@Nullable
		NE getSingleResult();
		
		@NonNull
		List<NE> getAllResults();
		
		int size();
	}
			''');
			writer.close();
		}
	}
	
	protected def void generateAutoLookupResultClass(/*@NonNull*/ EPackage ePackage) {
		var boolean isDerived = isDerived();
		if (!isDerived) {
			var MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + projectPrefix + "LookupResultImpl.java");
			writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»
	
	import java.util.ArrayList;
	import java.util.Collections;
	import java.util.List;
	
	import org.eclipse.jdt.annotation.NonNull;
	import org.eclipse.jdt.annotation.Nullable;
	
	public class «projectPrefix»LookupResultImpl<NE> implements «projectPrefix»LookupResult<NE> {
		
		private @NonNull List<NE> results = new ArrayList<NE>();
		
		public «projectPrefix»LookupResultImpl(List<NE> results){
			this.results.addAll(results);
		}
		
		@Override
		public @NonNull List<NE> getAllResults() {
			return Collections.unmodifiableList(results);
		}
		
		@Override
		public @Nullable NE getSingleResult() {
			return results.size() == 0 ? null : results.get(0);
		}
		
		@Override
		public int size() {
			return results.size();
		}
	}
			''');
			writer.close();
		}
	}
	
	protected def void generateAutoLookupFilterItf(/*@NonNull*/ EPackage ePackage) {
		val boolean isDerived = isDerived();
		if (!isDerived) {
			val itfName =  '''«projectPrefix»LookupFilter'''
			val MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + itfName + ".java");
			writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»
	
	import org.eclipse.jdt.annotation.NonNull;
	import «modelPackageName».NamedElement;

	/**
	 * 
	 */
	public interface «itfName» {
		
		boolean matches(@NonNull NamedElement namedElement);
		
	}
			''');
			writer.close();
		}
	}
	
	protected def void generateAutoLookupFilterClass(/*@NonNull*/ EPackage ePackage) {
		val boolean isDerived = isDerived();
		if (!isDerived) {
			val className =  '''Abstract«projectPrefix»LookupFilter''';
			val itfName =  '''«projectPrefix»LookupFilter'''
			val MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + className + ".java");
			writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»
	
	import org.eclipse.jdt.annotation.NonNull;
	import «modelPackageName».NamedElement;

	/**
	 * 
	 */
	public abstract class «className»<C extends NamedElement> implements «itfName» {
		
		@NonNull private Class<C> _class;
		
		public «className»(@NonNull Class<C> _class) {
			this._class = _class;
		}
		
		@SuppressWarnings("unchecked")
		@Override
		public boolean matches(@NonNull NamedElement namedElement) {
			return _class.isInstance(namedElement) && _matches((C)namedElement);
		}
		
		abstract protected Boolean _matches(@NonNull C element);
	}
			''');
			writer.close();
		}
	}
	protected def void generateSingleResultLookupEnvironment(/*@NonNull*/ EPackage ePackage) { 
		
		var boolean isDerived = isDerived();
		var className = projectPrefix + "SingleResultLookupEnvironment";
		if (!isDerived) {
			var MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + className+ ".java");
			writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»
	
	import java.util.ArrayList;
	import java.util.Collection;
	import java.util.List;
	
	import org.eclipse.emf.ecore.EClass;
	import org.eclipse.jdt.annotation.NonNull;
	import org.eclipse.jdt.annotation.Nullable;
	import org.eclipse.ocl.pivot.evaluation.Executor;
	
	import «modelPackageName».NamedElement;
	import «lookupPackageName».LookupEnvironment;
	import «lookupPackageName».impl.LookupEnvironmentImpl;
	
	public class «className» extends LookupEnvironmentImpl   {
		
		private @NonNull Executor executor;
		private @NonNull String name;
		private @NonNull EClass typeFilter;
		private @Nullable «projectPrefix»LookupFilter expFilter;
		
		public «className»(@NonNull Executor executor, /*@NonNull*/ EClass typeFilter, /*@NonNull*/ String name,  @Nullable «projectPrefix»LookupFilter expFilter) {
			assert typeFilter != null;
			assert name != null;
			this.executor = executor;
			this.name = name;
			this.typeFilter = typeFilter;
			this.expFilter = expFilter;
		}
	
		public «className»(@NonNull Executor executor, /*@NonNull*/ EClass typeFilter, /*@NonNull*/ String name) {
			this(executor, typeFilter, name, null);
		}
		
		@Override
		@NonNull
		public Executor getExecutor() {
			return executor;
		}
		
		@Override
		public boolean hasFinalResult() {
			for (NamedElement element : getNamedElements()) {
				if (name.equals(element.getName())) {
					return true;
				}
			}
			return false;
		}
		
		@Override
		@NonNull
		public LookupEnvironment addElement(@Nullable NamedElement namedElement) {
			if (namedElement != null) {
				if (name.equals(namedElement.getName())) {
					if (typeFilter.isInstance(namedElement)) {
					    «projectPrefix»LookupFilter expFilter2 = expFilter;
						if (expFilter2 == null || expFilter2.matches(namedElement)) {
							List<NamedElement> elements = getNamedElements();
							if (!elements.contains(namedElement)) { 	// FIXME use a set ?
								elements.add(namedElement);
							}
						}
					}
				}
			}
			return this;
		}
		
		@Override
		@NonNull
		public <NE extends NamedElement > LookupEnvironment addElements(
				@Nullable Collection<NE> namedElements) {
			
			if (namedElements != null) {
				for (NamedElement namedElement : namedElements) {
					addElement(namedElement);
				}	
			}
			return this;
		}
		
		@SuppressWarnings("unchecked")
		public <NE extends NamedElement> List<NE> getNamedElementsByKind(Class<NE> class_) {
			List<NE> result = new ArrayList<NE>(); 
			for (NamedElement namedElement : getNamedElements()) {
				if (class_.isAssignableFrom(namedElement.getClass())) {
					result.add((NE)namedElement);
				}
			}
			return result;
		}
	}
			''');
			writer.close();
		}
	}
	
	protected def void generateAutoLookupSolver(GenPackage genPackage, GenPackage basePackage) {
		var EPackage ePackage = genPackage.getEcorePackage;
		var String fqPackageItf = genModelHelper.getQualifiedPackageInterfaceName(ePackage)
		var List<Operation> lookupOps = basePackage.lookupMethods;
		var boolean isDerived = isDerived();
		var String className = projectPrefix + "LookupSolver";
		var String superClassName = superProjectPrefix + "LookupSolver";
		var MergeWriter writer = new MergeWriter(lookupArtifactsOutputFolder + className + ".java");
		writer.append('''
	«ePackage.generateHeaderWithTemplate(lookupArtifactsJavaPackage)»

	import org.eclipse.jdt.annotation.NonNull;
	import org.eclipse.ocl.pivot.evaluation.Executor;
	«FOR typeName : lookupOps.getLookupTypeNames("Unqualified")»
	import «visitorPackageName».«projectPrefix»Unqualified«typeName»LookupVisitor;
	«ENDFOR»
	«FOR typeName : lookupOps.getLookupTypeNames("Exported")»
	import «visitorPackageName».«projectPrefix»Exported«typeName»LookupVisitor;
	«ENDFOR»
	«FOR typeName : lookupOps.getLookupTypeNames("Qualified")»
	import «visitorPackageName».«projectPrefix»Qualified«typeName»LookupVisitor;
	«ENDFOR»
	
	«IF isDerived»
	import «superLookupPackageName».util.«superClassName»;
	import «baseLookupPackageName».util.«basePackage.prefix»LookupResult;
	import «baseLookupPackageName».util.«basePackage.prefix»LookupResultImpl;
	import «baseLookupPackageName».util.«basePackage.prefix»SingleResultLookupEnvironment;
	«ENDIF»
	
	public class «className»«IF isDerived» extends «superClassName»«ENDIF» {
		
		«IF !isDerived»protected final @NonNull Executor executor;
		
		«ENDIF»
		public «className» (@NonNull Executor executor) {
			«IF isDerived»
			super(executor);
			«ELSE»
			this.executor = executor;
			«ENDIF»
		}
		
		«FOR op : lookupOps»
		«val opName = op.name»
		«val isExportedLookup = op.exportedLookupOperation»
		«val lookupVisitorName = op.getLookupVisitorName(op.type.name)»
		«val hasAdditionalFilter = op.hasAdditionalFilterArgs»
		«val lookupVars = op.getLookupArgs»
		«val typeFQName = getTypeFQName(op.type)»
		«val typeLiteral = getTypeLiteral(op.type)»
		
		public «basePackage.prefix»LookupResult<«typeFQName»> «opName»(«getTypeFQName(op.owningClass)» context«FOR param:op.ownedParameters», «getTypeFQName(param.type)» «param.name»«ENDFOR») {
			«IF hasAdditionalFilter»
			«op.type.name»Filter filter = new «op.type.name»Filter(executor, «op.getFilterArgs»);
			«ENDIF»
			«basePackage.prefix»SingleResultLookupEnvironment _lookupEnv = new «basePackage.prefix»SingleResultLookupEnvironment(executor, «fqPackageItf».Literals.«typeLiteral»«lookupVars»);
			«lookupVisitorName» _lookupVisitor = new «lookupVisitorName»(_lookupEnv«IF isExportedLookup», importer«ENDIF»);
			context.accept(_lookupVisitor);
			return new «basePackage.prefix»LookupResultImpl<«typeFQName»>
					(_lookupEnv.getNamedElementsByKind(«typeFQName».class));
		}
		«ENDFOR»
	}
		''');
		writer.close();
	}
		
	protected def void generateAutoCommonLookupVisitor(EPackage ePackage) {
		var String fqPackageItf = genModelHelper.getQualifiedPackageInterfaceName(ePackage)

		var boolean isDerived = isDerived();
		var String visitorName = '''Abstract«projectPrefix»CommonLookupVisitor''';
		var String superVisitorName = '''Abstract«superProjectPrefix»CommonLookupVisitor''';
		var String superClassName = '''AbstractExtending«IF isDerived»«projectPrefix»«ENDIF»Visitor'''
		var MergeWriter writer = new MergeWriter(outputFolder + visitorName + ".java");
		writer.append('''
	«ePackage.generateHeaderWithTemplate(visitorPackageName)»
	import org.eclipse.jdt.annotation.NonNull;
	import org.eclipse.jdt.annotation.Nullable;
	import org.eclipse.ocl.pivot.internal.evaluation.EvaluationCache;
	«IF !isDerived»	
	import org.eclipse.ocl.pivot.internal.evaluation.ExecutorInternal.ExecutorInternalExtension;
	«ENDIF»	
	
	import «baseLookupPackageName».LookupEnvironment;
	import «visitablePackageName».«visitableClassName»;
	«IF isDerived»	
	import «superVisitorPackageName».«superVisitorName»;
	«ENDIF»	
	
	public abstract class «visitorName»
		extends «superClassName»<@Nullable LookupEnvironment, @NonNull LookupEnvironment> {
	
		«IF !isDerived»protected final @NonNull EvaluationCache evaluationCache;«ENDIF»
		«IF isDerived»private «superVisitorName» delegate;«ENDIF»
		
		protected «visitorName»(@NonNull LookupEnvironment context) {
			super(context);
			«IF !isDerived»this.evaluationCache = ((ExecutorInternalExtension)context.getExecutor()).getEvaluationCache();«ENDIF»
			«IF isDerived»this.delegate = createSuperLangVisitor();«ENDIF»
		}
		
		@Override
		public final LookupEnvironment visiting(@NonNull Visitable visitable) {
			«IF isDerived»
			return «fqPackageItf».eINSTANCE == visitable.eClass().getEPackage()
				? doVisiting(visitable)
				: visitable.accept(getSuperLangVisitor());
			«ELSE»
			return doVisiting(visitable);
			«ENDIF»
		}
		
		«IF isDerived»
		protected «superVisitorName» getSuperLangVisitor(){
			if (delegate == null) {
				delegate = createSuperLangVisitor();
			}
			return delegate;
		}
		«ENDIF»
		
		abstract protected LookupEnvironment doVisiting(@NonNull Visitable visitable);
		
		«IF isDerived»abstract protected «superVisitorName»  createSuperLangVisitor();«ENDIF»
	}
		''')
		writer.close();
	}
	
	override generateVisitors(GenPackage genPackage) {		
		genModelHelper = createGenModelHelper(genPackage);
		lookupArtifactsJavaPackage = lookupPackageName + ".util";
		lookupArtifactsOutputFolder = modelFolder + lookupArtifactsJavaPackage.replace('.', '/') + "/";
		
		var EPackage ePackage = genPackage.getEcorePackage();
		
		// Some lookup artefacts
		ePackage.generateAutoLookupResultClass;
		ePackage.generateAutoLookupResultItf;
		ePackage.generateAutoLookupFilterItf;
		ePackage.generateAutoLookupFilterClass;
		ePackage.generateSingleResultLookupEnvironment;
		genPackage.generateAutoLookupSolver(baseGenPackage);
		
		// Visitors related generation
		ePackage.generateAutoCommonLookupVisitor;
		doGenerateVisitors(genPackage);
	}
	
	private def List<Operation> getLookupMethods(GenPackage genPackage) {
		
		var List<Operation> result = new ArrayList<Operation>;
		var EnvironmentFactory envFact = PivotUtilInternal.getEnvironmentFactory(genPackage.getEcorePackage.eResource)
		for (oclPackage : LookupCGUtil.getTargetPackages(genPackage, envFact, lookupFilePath, projectName)) {
			for (oclClass : oclPackage.ownedClasses) {
				for (oclOp : oclClass.ownedOperations) {
					if (oclOp.isLookupOperation) {
						result.add(oclOp);
					}
				}
			}
		} 
		return result;
	}
	
	private def Set<String> getLookupTypeNames(List<Operation> lookupOps, String lookupProtocol) {
		
		val result = newHashSet();
		for (op : lookupOps) {
			if (op.name.contains(lookupProtocol)){
				result.add(op.type.name);
			}
		}
		return result;
	}
		
	private def boolean isLookupOperation(Operation op){
		// internal lookup ops...
		if (!op.name.startsWith("_lookup")) {
			return false;
		}
	
		// ...which don't have the env parameter
		// FIXME more robust check of the parameter
		for (param : op.ownedParameters) {
			if ("env".equals(param.name)) {
				return false
			}
		}
		
		return true;
	}
	
	private def boolean isExportedLookupOperation(Operation op) {
		isLookupOperation(op) && op.name.contains("Exported") // FIXME more robust check?
	}
	
	private def GenModelHelper createGenModelHelper(GenPackage genPackage) {
		var PivotMetamodelManager mManager = PivotUtilInternal.getEnvironmentFactory(genPackage.getEcorePackage().eResource).metamodelManager;
		return new AbstractGenModelHelper(mManager);
	}
	
	private def String getTypeLiteral(Type type) {
		var GenClassifier genClassifier = genModelHelper.getGenClassifier(type as Class);
		return ClassUtil.nonNullState(genClassifier).classifierID; 
	}
	
	private def String getTypeFQName(Type type) {
		return if (type instanceof CollectionType) '''java.util.List<«getTypeFQName(type.elementType)»>''' 
			else genModelHelper.getEcoreInterfaceName(type as Class)	
	}
	
	private def String getLookupVisitorName(Operation op, String typeName) {

		if (op.name.contains("Qualified")) '''«projectPrefix»Qualified«typeName»LookupVisitor'''
		else if (op.name.contains("Exported")) '''«projectPrefix»Exported«typeName»LookupVisitor'''
		else '''«projectPrefix»Unqualified«typeName»LookupVisitor''';	
	}

	
	private def boolean hasAdditionalFilterArgs(Operation op) {
		val params = op.ownedParameters;
		if (op.isExportedLookupOperation) params.size() > 2 else params.size() > 1;
	}
	
	private def String getLookupArgs(Operation op) {
		val params = op.ownedParameters
		val nameParam = if (op.isExportedLookupOperation) params.get(1) else params.get(0);
		''',«nameParam.name»«IF op.hasAdditionalFilterArgs»,filter«ENDIF»'''
	}
	
	// We assume we are dealing with the the exported element lookup op
	private def String getFilterArgs(Operation op) {
		val sb = new StringBuffer();
		val filterArgsIndex = if (op.isExportedLookupOperation) 2 else 1;
		val params = op.ownedParameters
		var first=true;
		for (var i = filterArgsIndex; i < params.size; i++) {
			if (first) {
				first = false
			} else {
				sb.append(',');	
			}
			sb.append('''«params.get(i).name»''');
		}
		sb.toString();
	}
	
}
