/**
 *                                                                            
 *  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 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.simpleName»«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;
	}

}
