/**
 *                                                                            
 *  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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  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 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.DomainDescription
import org.eclipse.osbp.runtime.common.annotations.DomainKey
import org.eclipse.osbp.runtime.common.annotations.Properties
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.JvmField
import org.eclipse.xtext.common.types.JvmStringAnnotationValue
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.common.types.JvmIntAnnotationValue
import org.eclipse.osbp.runtime.common.annotations.FilterDepth

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)
	}

	/**
	 * 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;
		}

	}

}
