/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */

package org.eclipse.osbp.autowirehelper.utils

import java.util.List
import java.util.Map
import java.util.function.Function
import javax.inject.Inject
import org.apache.commons.lang.StringEscapeUtils
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedReference
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.ecview.dsl.extensions.BindableTypeResolver
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions.OperationInfo
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot
import org.eclipse.osbp.ecview.semantic.uimodel.UiLayout
import org.eclipse.osbp.ecview.semantic.uimodel.UiModel
import org.eclipse.osbp.ecview.semantic.uimodel.UiView
import org.eclipse.osbp.ecview.semantic.uimodel.impl.UiViewImpl
import org.eclipse.osbp.runtime.common.annotations.CompareType
import org.eclipse.osbp.runtime.common.annotations.DomainDescription
import org.eclipse.osbp.runtime.common.annotations.DomainKey
import org.eclipse.osbp.runtime.common.annotations.FilterDepth
import org.eclipse.osbp.runtime.common.annotations.Properties
import org.eclipse.osbp.runtime.common.annotations.TargetEnumConstraints
import org.eclipse.osbp.utils.common.EntityUtils
import org.eclipse.xtext.common.types.JvmAnnotationAnnotationValue
import org.eclipse.xtext.common.types.JvmAnnotationReference
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.JvmEnumAnnotationValue
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmIntAnnotationValue
import org.eclipse.xtext.common.types.JvmStringAnnotationValue
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.JvmTypeAnnotationValue
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.naming.IQualifiedNameProvider

class AutowireUtil {
	@Inject extension IQualifiedNameProvider
	@Inject extension TypeHelper
	@Inject
	private TypeReferences typeReferences;

	public def String generateId(UiLayout layout) {
		val BindableTypeResolver resolver = new BindableTypeResolver
		var resolvedType = resolver.resolveType(layout.autoWireSource)
		var viewName = ""

		var parent = layout.eContainer
		while (!(parent instanceof UiModel)) {
			if (parent instanceof UiViewImpl) {
				viewName = (parent as UiViewImpl).name
			}
			parent = parent.eContainer
		}
		var uimodel = parent as UiModel
		return '''«uimodel.packageName»«IF viewName != null».«viewName»«ENDIF»«IF resolvedType != null».«resolvedType.
			identifier»«ENDIF»'''
	}

	public def UiView getUiView(UiLayout layout) {
		var parent = layout.eContainer
		while (!(parent instanceof UiViewImpl)) {
			parent = parent.eContainer
		}
		if (parent instanceof UiViewImpl) {
			return (parent as UiViewImpl)
		}
	}

	public def boolean isAttribute(JvmType type, String attribute, String filterName) {
		var dto = EntityUtils.getDto(type)
		if (dto != null) {
			var attr = dto.attributes.findFirst[toName == attribute]
			if (attr != null) {
				var datatype = attr.toDatatype as LDataType
				return datatype.name == filterName
			}
		}
		return false
	}

	/**
	 * Detects all the existing properties of the jvmtype corresponding attribute, the datatype of the attribute and references. 
	 */
	public def List<Pair> toProperties(JvmDeclaredType type, String attributeName) {
		val result = type.toFieldProperties.get(attributeName)
		if (result != null) {
			for (prop : result) {

				// unescape quotes like &curren; to avoid UTF-8 conflicts
				prop.value = StringEscapeUtils.unescapeHtml(prop.value);
			}
		}
		return if(result != null) result else newArrayList()
	}

	/**
	 * Detects all the existing properties of the jvmtype corresponding reference and the referenced dto. 
	 */
	public def Map<String, List<Pair>> toFieldProperties(JvmDeclaredType jvmType) {
		val Map<String, List<Pair>> propMap = newHashMap()
		jvmType.allFeatures.filter(typeof(JvmField)).forEach [
			val attrPropKey = '''«jvmType.qualifiedName».«it.simpleName»'''
			val List<Pair> values = newArrayList()
			propMap.put(attrPropKey, values)
			it.annotations.filter [ e |
				val result = e.annotation.identifier.equals(typeof(Properties).name)
				return result
			].forEach [
				val JvmAnnotationReference ref = it;
				ref.values.map[it as JvmAnnotationAnnotationValue].forEach [ av |
					av.values.forEach [
						val keyAn = it.values.get(0) as JvmStringAnnotationValue
						val valueAn = it.values.get(1) as JvmStringAnnotationValue
						values.add(new Pair(keyAn.values.get(0), valueAn.values.get(0)))
					]
				]
			]
		]

		return propMap
	}

	/**
	 * Returns the depth of the filter for BeanReferenceFields
	 */
	public def int toFilterDepth(JvmField field) {
		val ref = field.annotations.findFirst [ e |
			val result = e.annotation.identifier.equals(typeof(FilterDepth).name)
			return result
		]

		if (ref === null) {
			return 0
		}

		val JvmIntAnnotationValue depthVal = ref.values.get(0) as JvmIntAnnotationValue
		return depthVal.values.get(0)
	}

	/**
	 * Returns info about the TargetEnumConstraints annotation.
	 * 
	 * usage:
	 * 				
				val targets = toEnumReferenceConstraint(info.field, [
					return computer.loadClass(uiLayout?.eResource?.resourceSet, it.qualifiedName)
				])
	 
	 * 
	 * 
	 */
	public def List<TargetEnumProps> toEnumReferenceConstraint(JvmField jvmField,
		Function<JvmType, Class<?>> typeProvider) {
		val List<TargetEnumProps> targets = newArrayList;
		jvmField.annotations.filter [ e |
			val result = e.annotation.identifier.equals(typeof(TargetEnumConstraints).name)
			return result
		].forEach [
			val JvmAnnotationReference ref = it;
			ref.values.map[it as JvmAnnotationAnnotationValue].forEach [ av |
				av.values.forEach [
					val target = new TargetEnumProps
					target.targetProperty = (it.values.get(0) as JvmStringAnnotationValue).values.get(0)
					val enumClassJvmType = (it.values.get(1) as JvmTypeAnnotationValue).values.get(0)
					target.enumClass = typeProvider.apply(enumClassJvmType.type)

					target.enumLiteral = (it.values.get(2) as JvmStringAnnotationValue).values.get(0)
					target.compareType = CompareType.valueOf(
						(it.values.get(3) as JvmEnumAnnotationValue).values.get(0).simpleName)
					targets += target
				]
			]
		]

		return targets
	}

	/**
	 * Detects all the existing properties of the jvmtype corresponding datatype of the attribute. 
	 */
	public def LDataType toDataType(JvmType type, String attributeName) {
		var dto = EntityUtils.getDto(type)
		if (dto != null) {
			var attr = dto.attributes.findFirst[toName == attributeName]
			if (attr != null) {
				var dataType = attr.toDatatype
				if (dataType instanceof LDataType) {
					return (attr.toDatatype as LDataType)
				}
			}
		}
		return null
	}

	/**
	 * Provides the datatype of the corresponding attribute. 
	 */
	public def List<LKeyAndValue> toDataTypeProperties(JvmType type, String attributeName) {
		var dataType = type.toDataType(attributeName)
		if (dataType != null) {
			return dataType.properties
		}
		return newArrayList()
	}

	def String toName(LDtoFeature feature) {
		if (feature instanceof LDtoInheritedAttribute) {
			return feature.inheritedFeature.name
		} else if (feature instanceof LDtoInheritedReference) {
			return feature.inheritedFeature.name
		} else {
			return feature.name
		}
	}

	def LScalarType toDatatype(LDtoAbstractAttribute att) {
		if (att instanceof LDtoInheritedAttribute) {
			return att.inheritedFeature.type
		} else {
			return att.type
		}
	}

	def boolean isBlob(JvmType type, String attribute) {
		var dto = EntityUtils.getDto(type)
		var attrs = dto.attributes.filter[name == attribute]
		for (attr : attrs) {
			var datatype = attr.type as LDataType
			println(datatype)
			return datatype.asBlob
		}
		return false
	}

	def String getEntityName(UiBeanSlot uiBeanSlot) {
		val entity = EntityUtils.getEntityFromDto(uiBeanSlot.jvmType.type) as LEntity
		var String eName
		if (entity == null) {
			if (uiBeanSlot.jvmType.type == null) {
				eName = ""
			} else if (uiBeanSlot.jvmType.type != null) {

				// Temporary solution till final solution found.
				// eName = uiBeanSlot.jvmType.type.toString
				eName = ""
			}
		} else {
			eName = entity.name
		}
		return eName
	}

	// Helper Methods
	def boolean isClass(JvmType type) {
		if (typeReferences.is(type, Class)) {
			return true;
		}
		return false;
	}

	// Helper Methods
	def boolean isByteArray(JvmType type) {
		if (typeReferences.is(type, typeof(byte[]))) {
			return true;
		}
		return false;
	}

	def boolean isAllowed(JvmType type, JvmType beanType, OperationInfo info) {
		if (type.numberWithDigits) {
			return true
		} else if (type.numberWithoutDigits) {
			return true
		} else if (type.string) {
			return true
		} else if (type.date) {
			return true
		} else if (type.byteArray) {
			return true
		} else if (type.boolean) {
			return true
		} else if (type.enum) {
			return true
		} else if (info.domainReference) {
			switch (type) {
				JvmDeclaredType:
					if ((type as JvmDeclaredType).isAnnotationOf(typeof(DomainKey)) ||
						(type as JvmDeclaredType).isAnnotationOf(typeof(DomainDescription))) {
						return true
					}
			}
			return false
		} else if (info.field != null && info.field.collection) {
			return true
		}
		return false
	}

	private def boolean isAnnotationOf(JvmDeclaredType type, Class<?> clazz) {
		for (member : type.members) {
			for (annotation : member.annotations) {
				if (annotation.annotation.identifier.equals(clazz.canonicalName)) {
					return true
				}
			}
		}
		for (superType : type.superTypes) {
			if (superType.type instanceof JvmDeclaredType) {
				return isAnnotationOf((superType.type as JvmDeclaredType), clazz)
			}
		}
		return false
	}

	static class Pair {
		public String key
		public String value

		new(String key, String value) {
			this.key = key;
			this.value = value;
		}

	}

	public static class TargetEnumProps {
		/**
		 * The property of the target type of the reference that must match the enum
		 * literal.
		 * 
		 * @return the string
		 */
		String targetProperty;

		/**
		 * The enum class used to get the enum literal.
		 * 
		 * @return the class
		 */
		Class<?> enumClass;

		/**
		 * The name of the enum literal that is used as a filter.
		 * 
		 * @return the string
		 */
		String enumLiteral;

		/**
		 * The compareType used to execute the filter.
		 * 
		 * @return the compare type
		 */
		CompareType compareType = CompareType.EQUALS;
	}

}
