/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.common.xtext.jvmmodel

import com.google.inject.Inject
import java.util.List
import java.util.ListIterator
import javax.validation.Valid
import javax.validation.constraints.AssertFalse
import javax.validation.constraints.AssertTrue
import javax.validation.constraints.DecimalMax
import javax.validation.constraints.DecimalMin
import javax.validation.constraints.Digits
import javax.validation.constraints.Future
import javax.validation.constraints.Max
import javax.validation.constraints.Min
import javax.validation.constraints.NotNull
import javax.validation.constraints.Null
import javax.validation.constraints.Past
import javax.validation.constraints.Pattern
import javax.validation.constraints.Size
import org.eclipse.emf.ecore.EObject
import org.eclipse.osbp.dsl.common.xtext.extensions.AnnotationExtension
import org.eclipse.osbp.dsl.semantic.common.types.LAnnotationTarget
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.common.types.LDatatypeConstraint
import org.eclipse.osbp.dsl.semantic.common.types.LDtCAssertFalse
import org.eclipse.osbp.dsl.semantic.common.types.LDtCAssertTrue
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDecimalMax
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDecimalMin
import org.eclipse.osbp.dsl.semantic.common.types.LDtCDigits
import org.eclipse.osbp.dsl.semantic.common.types.LDtCFuture
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNotNull
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNull
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNumericMax
import org.eclipse.osbp.dsl.semantic.common.types.LDtCNumericMin
import org.eclipse.osbp.dsl.semantic.common.types.LDtCPast
import org.eclipse.osbp.dsl.semantic.common.types.LDtCRegEx
import org.eclipse.osbp.dsl.semantic.common.types.LDtCSize
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue
import org.eclipse.osbp.dsl.semantic.common.types.LOperation
import org.eclipse.osbp.dsl.semantic.common.types.LReference
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType
import org.eclipse.osbp.dsl.semantic.common.types.LType
import org.eclipse.osbp.runtime.common.annotations.Dirty
import org.eclipse.osbp.runtime.common.annotations.Properties
import org.eclipse.osbp.runtime.common.annotations.Property
import org.eclipse.osbp.runtime.common.validation.ErrorSeverity
import org.eclipse.xtext.common.types.JvmAnnotationReference
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmMember
import org.eclipse.xtext.common.types.JvmOperation
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.osbp.runtime.common.validation.InfoSeverity
import org.eclipse.osbp.runtime.common.validation.WarningSeverity

/** 
 * This class is responsible to generate the Annotations defined in the entity model
 */
class AnnotationCompiler {

	@Inject extension JvmTypesBuilder
	@Inject extension AnnotationExtension
	@Inject extension TypeReferences

	def processAnnotation(LAnnotationTarget annotationTarget, JvmMember jvmMember) {
		internalProcessAnnotation(annotationTarget, jvmMember)
	}

	def protected dispatch void internalProcessAnnotation(LType bean, JvmGenericType jvmType) {
		bean.resolvedAnnotations.filter([!exclude]).map([annotation]).translateAnnotationsTo(jvmType);
	}

	def protected dispatch void internalProcessAnnotation(LReference ref, JvmField jvmType) {
		ref.resolvedAnnotations.filter([!exclude]).map([annotation]).translateAnnotationsTo(jvmType);
	}

	def protected dispatch void internalProcessAnnotation(LAttribute att, JvmField jvmType) {
		att.resolvedAnnotations.filter([!exclude]).map([annotation]).translateAnnotationsTo(jvmType);
	}

	def void toDatatypeBasedConstraintAnnotations(LAttribute att, JvmField jvmType) {
		if (att.type instanceof LDataType) {
			val LDataType dt = att.type as LDataType;
			for (c : dt.constraints) {
				c.toConstraintAnnotation(jvmType)
			}
		}
	}

	def protected List<LKeyAndValue> mergeKeyAndValues(LAttribute att) {
		val keyAndValues = newArrayList()

		// add all datatype properties to the list
		att.addDatatypeKeyAndValues(keyAndValues)

		// add the attribute properties
		keyAndValues.addAll(att.properties)

		// remove duplicate keys
		keyAndValues.removeDuplicateKeys

		return keyAndValues
	}

	def protected List<LKeyAndValue> mergeKeyAndValues(LReference ref) {
		val keyAndValues = newArrayList()

		// add the attribute properties
		keyAndValues.addAll(ref.properties)

		// remove duplicate keys
		keyAndValues.removeDuplicateKeys

		return keyAndValues
	}

	def protected void removeDuplicateKeys(List<LKeyAndValue> result) {

		if (result.size == 0) {
			return
		}

		val keys = newArrayList()

		val ListIterator<LKeyAndValue> iter = result.listIterator(result.size - 1)
		while (iter.hasPrevious) {
			val LKeyAndValue temp = iter.previous
			if (keys.contains(temp.key)) {
				iter.remove
			} else {
				keys += temp.key
			}
		}
	}

	def protected addDatatypeKeyAndValues(LAttribute att, List<LKeyAndValue> result) {
		if (att.type instanceof LDataType) {
			val LDataType dt = att.type as LDataType
			result.addAll(dt.properties)
		}
	}

	def protected void toPropertiesAnnotation(EObject context, List<LKeyAndValue> keyValues, JvmField field) {
		if (keyValues == null || keyValues.size == 0) {
			return
		}
		val innerAnnotations = newArrayList()
		keyValues.forEach [
			val innerAnno = context.toAnnotation(typeof(Property))
			innerAnno.addAnnAttr(it, "key", key)
			innerAnno.addAnnAttr(it, "value", value)
			innerAnnotations += innerAnno
		]

		// now create the outer annotation and add the array of inner annotations
		val mainAnno = context.toAnnotation(typeof(Properties))
		mainAnno.addAnnAttr(context, "properties",
			innerAnnotations.toArray(<JvmAnnotationReference>newArrayOfSize(innerAnnotations.length)))
		field.annotations += mainAnno

	}

	/**
	 * Annotation to tell validator, that nested properties should be validated too
	 */
	def protected void toValidAnnotation(EObject context, JvmField field) {
		val anno = context.toAnnotation(typeof(Valid))
		field.annotations += anno
	}

	/**
	 * Annotation for the dirty state
	 */
	def void toDirtyAnnotation(EObject context, JvmField field) {
		val anno = context.toAnnotation(typeof(Dirty))
		field.annotations += anno
	}

	def dispatch boolean isValidAllowed(Void voidx) {
		return false
	}

	def dispatch boolean isValidAllowed(LDataType type) {
		if (type.asPrimitive) {
			return false
		}

		if (type.jvmTypeReference?.qualifiedName.isPrimitiveJvmType) {
			return false
		}

		return true
	}

	def dispatch boolean isValidAllowed(LScalarType type) {
		return false;
	}

	def boolean isPrimitiveJvmType(String value) {
		if (value == null) {
			return false
		}

		switch (value) {
			case (typeof(Integer).name ):
				return true
			case Integer.TYPE.name:
				return true
			case typeof(Boolean).name:
				return true
			case Boolean.TYPE.name:
				return true
			case typeof(Short).name:
				return true
			case Short.TYPE.name:
				return true
			case typeof(Long).name:
				return true
			case Long.TYPE.name:
				return true
			case typeof(Double).name:
				return true
			case Double.TYPE.name:
				return true
			case typeof(Float).name:
				return true
			case Float.TYPE.name:
				return true
			case typeof(Character).name:
				return true
			case Character.TYPE.name:
				return true
			case typeof(Byte).name:
				return true
			case Byte.TYPE.name:
				return true
			case typeof(Boolean).name:
				return true
			case Boolean.TYPE.name:
				return true
			case typeof(String).name:
				return true
		}
		return false
	}

	def protected dispatch void toConstraintAnnotation(LDtCAssertFalse constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(AssertFalse))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	protected def handlePayloadAndMessages(LDatatypeConstraint constraint, JvmAnnotationReference anno) {

		// TODO OSBP right now vaadin does not support INFO and WARNING.
		switch (constraint.severity) {
			case INFO:
				anno.addAnnAttr(constraint, "payload", typeof(InfoSeverity).getTypeForName(constraint))
			case WARNING:
				anno.addAnnAttr(constraint, "payload", typeof(WarningSeverity).getTypeForName(constraint))
			case ERROR:
				anno.addAnnAttr(constraint, "payload", typeof(ErrorSeverity).getTypeForName(constraint))
		}
//		anno.addAnnAttr(constraint, "payload", typeof(ErrorSeverity).getTypeForName(constraint))

		val b = new StringBuilder
		if (!constraint.msgI18nKey.nullOrEmpty) {
			b.append(constraint.msgI18nKey)
		}

		if (!constraint.msgCode.nullOrEmpty) {
			b.append(":")
			b.append(constraint.msgCode)
		}

		if (!b.toString.nullOrEmpty) {
			anno.addAnnAttr(constraint, "message", "{" + b.toString + "}")
		}
	}

	def protected dispatch void toConstraintAnnotation(LDtCAssertTrue constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(AssertTrue))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCNotNull constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(NotNull))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCNull constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Null))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCFuture constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Future))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCPast constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Past))
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCSize constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Size))
		if (constraint.min >= 0) {
			anno.addAnnAttr(constraint, "min", constraint.min)
		}
		if (constraint.max > 0) {
			anno.addAnnAttr(constraint, "max", constraint.max)
		}

		handlePayloadAndMessages(constraint, anno)

		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCDigits constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Digits))
		if (constraint.intDigits >= 0) {
			anno.addAnnAttr(constraint, "integer", constraint.intDigits)
		}
		if (constraint.fractionDigits > 0) {
			anno.addAnnAttr(constraint, "fraction", constraint.fractionDigits)
		}

		handlePayloadAndMessages(constraint, anno)

		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCDecimalMax constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(DecimalMax))
		anno.addAnnAttr(constraint, "value", constraint.max.toString)
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCDecimalMin constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(DecimalMin))
		anno.addAnnAttr(constraint, "value", constraint.min.toString)
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCNumericMax constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Max))
		anno.addAnnAttr(constraint, "value", constraint.max)
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCNumericMin constraint, JvmField field) {
		val anno = constraint.toAnnotation(typeof(Min))
		anno.addAnnAttr(constraint, "value", constraint.min)
		handlePayloadAndMessages(constraint, anno)
		field.annotations += anno
	}

	def protected dispatch void toConstraintAnnotation(LDtCRegEx constraint, JvmField field) {
		if (constraint.pattern != null && !constraint.pattern.isEmpty) {
			val anno = constraint.toAnnotation(typeof(Pattern))
			anno.addAnnAttr(constraint, "regexp", constraint.pattern)
			handlePayloadAndMessages(constraint, anno)
			field.annotations += anno
		}
	}

	// def protected dispatch void toConstraintAnnotation(LDtCPast constraint, JvmField field) {
	// field.annotations += constraint.toAnnotation(typeof(Past))
	// }
	def protected dispatch void internalProcessAnnotation(LOperation member, JvmOperation jvmOperation) {
		member.resolvedAnnotations.filter([!exclude]).map([annotation]).translateAnnotationsTo(jvmOperation);
	}
}
