/**
 * 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.extensions

import com.google.inject.Inject
import java.util.Date
import java.util.List
import org.eclipse.emf.ecore.EObject
import org.eclipse.osbp.dsl.semantic.common.helper.Bounds
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.LClass
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.common.types.LEnum
import org.eclipse.osbp.dsl.semantic.common.types.LFeature
import org.eclipse.osbp.dsl.semantic.common.types.LPackage
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.dsl.semantic.common.types.LTypedPackage
import org.eclipse.xtext.common.types.JvmTypeReference
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder

class ModelExtensions {

	@Inject extension IQualifiedNameProvider
	@Inject extension JvmTypesBuilder

	@Inject TypeReferences references;
 
	def dispatch JvmTypeReference toTypeReference(LType type) {
		if (type === null || type.fullyQualifiedName === null) {
			return null
		}
		return type.newTypeRef(type.fullyQualifiedName.toString) 
	}

	def dispatch JvmTypeReference toTypeReference(LDataType type) {
		if (type.syntheticFlag) {
			return type.toSyntheticTypeReference
		} else if (type.date) {
			return references.findDeclaredType(typeof(Date), type).newTypeRef()
		} else if (type.asBlob) {
			val typeRef = references.findDeclaredType(Byte::TYPE, type).newTypeRef()
			return references.createArrayType(typeRef)
		} else if (type.asPrimitive) {
			val fqn = type?.jvmTypeReference?.type?.fullyQualifiedName
			switch (fqn.toString) {
				case typeof(Integer).name: references.findDeclaredType(Integer::TYPE, type).newTypeRef()
				case typeof(Boolean).name: references.findDeclaredType(Boolean::TYPE, type).newTypeRef()
				case typeof(Short).name: references.findDeclaredType(Short::TYPE, type).newTypeRef()
				case typeof(Long).name: references.findDeclaredType(Long::TYPE, type).newTypeRef()
				case typeof(Double).name: references.findDeclaredType(Double::TYPE, type).newTypeRef()
				case typeof(Float).name: references.findDeclaredType(Float::TYPE, type).newTypeRef()
				case typeof(Character).name: references.findDeclaredType(Character::TYPE, type).newTypeRef()
				case typeof(Byte).name: references.findDeclaredType(Byte::TYPE, type).newTypeRef()
				case typeof(Boolean).name: references.findDeclaredType(Boolean::TYPE, type).newTypeRef()
				default: type?.jvmTypeReference
			}
		} else {
			return type.jvmTypeReference.cloneWithProxies
		}
	}

	def String toNullReturnValue(LScalarType dt) {
		if(dt === null) return "null"

		if (dt instanceof LDataType) {

			if (dt.isBool) {
				return "Boolean.FALSE"
			}

			if (dt.isNumericOrWrapperType) {
				val fqn = dt?.jvmTypeReference?.type?.fullyQualifiedName
				switch (fqn.toString) {
					case typeof(Integer).name: return "0"
					case typeof(Short).name: return "0"
					case typeof(Long).name: return "0"
					case typeof(Double).name: return "0.0"
					case typeof(Float).name: return "0.0"
					case typeof(Character).name: return "0"
					case typeof(Byte).name: return "0"
				}
			}
		}

		return "null"

	}

	def boolean isNumericOrWrapperType(LDataType type) {
		val fqn = type?.jvmTypeReference?.type?.fullyQualifiedName
		if (fqn === null) {
			return false
		}
		switch (fqn.toString) {
			case typeof(Integer).name: return true
			case typeof(Short).name: return true
			case typeof(Long).name: return true
			case typeof(Double).name: return true
			case typeof(Float).name: return true
			case typeof(Character).name: return true
			case typeof(Byte).name: return true
			default: false
		}
	}

	def boolean isBool(LDataType type) {
		if (type.asPrimitive) {
			val fqn = type?.jvmTypeReference?.type?.fullyQualifiedName
			switch (fqn.toString) {
				case typeof(Boolean).name: return true
				default: return false
			}
		}
		return false
	}

	def boolean isString(LDataType type) {
		val fqn = type?.jvmTypeReference?.type?.qualifiedName
		return "java.lang.String".equals(fqn)
	}

	def boolean isDate(LDataType type) {
		return type.isDate
	}

	def dispatch boolean isPrimitive(LDataType type) {
		return type.asPrimitive;
	}

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

	def boolean isBasedOnDatatype(LFeature feature) {
		if (feature instanceof LAttribute) {
			return feature.type instanceof LDataType
		}
		return false
	}

	def LDataType getDatatype(LFeature feature) {
		if (feature instanceof LAttribute) {
			if (feature.type instanceof LDataType) {
				return feature.type as LDataType
			}
		}
		return null
	}

	def JvmTypeReference toSyntheticTypeReference(LDataType type) {
	}

//	/**
//	 * Returns true if jvm type proxies should be avoided for special datatypes like date or blob
//	 */
//	def boolean isAvoidJvmTypeProxiesForDatatype(LAttribute prop) {
//		if (prop.type instanceof LDataType) {
//
//			//			val LDataType lDt = prop.type as LDataType
//			//			return lDt.asBlob || lDt.date
//			return true
//		}
//		return false
//	}
	/**
	 * Creates a jvmTypeReference based on the datatype.
	 */
	def JvmTypeReference toDataTypeTypeReference(LAttribute prop) {
		val LDataType lDt = prop.type as LDataType
		return lDt.toTypeReference
	}

	def dispatch JvmTypeReference toTypeReference(LAttribute prop) {
		if (prop.type instanceof LDataType) {
			return prop.toDataTypeTypeReference
		} else {
			prop.type.toTypeReference
		}
	}

	/**
	 * Create a type reference with respect to many multiplicity
	 */
	def dispatch JvmTypeReference toTypeReferenceWithMultiplicity(LAnnotationTarget context) {
		var typeRef = context.toTypeReference
		if (typeRef !== null && context.bounds.toMany) {
			typeRef = context.toListTypeReference(typeRef)
		}
		return typeRef
	}

	def toListTypeReference(EObject context, JvmTypeReference jvmTypeRef) {
		newTypeRef(context, typeof(List), jvmTypeRef);
	}

	def dispatch Bounds getBounds(LFeature prop) {
		Bounds::createFor(prop)
	}

	def dispatch Bounds getBounds(LAnnotationTarget context) {
		Bounds::createZeroToOne
	}

	def dispatch Bounds getBounds(Void context) {
		Bounds::createZeroToOne
	}

	def isToMany(LFeature prop) {
		prop.bounds.toMany
	}

//	def dispatch boolean isCascading(LAttribute prop) {
//		prop.cascading
//	}
//
//	def dispatch boolean isCascading(LReference prop) {
//		prop.cascading
//	}

	def typeIsBoolean(LFeature prop) {
		val LDataType dt = prop.datatype
		if (dt === null) {
			return false
		}
		val typeRef = dt.jvmTypeReference
		return typeRef !== null && !typeRef.eIsProxy() && typeRef.getType() !== null && !typeRef.getType().eIsProxy() &&
			"boolean".equals(typeRef.getType().getIdentifier())
	}

	def typeIsEnum(LAttribute prop) {
		return prop.type instanceof LEnum
	}

	/**
	 * Returns true, if toCheck can be cast to superType
	 */
	def boolean nameEquals(LClass toCheck, LClass superType) {
		val String toCheckFqn = toCheck.fullyQualifiedName.toString
		val String superTypeFqn = superType.fullyQualifiedName.toString
		return toCheckFqn.equals(superTypeFqn);
	}

	/**
	 * Returns the {@link LPackage} for the given type.
	 * 
	 * @param lType
	 * @return
	 */
	def LPackage getPackage(LType lType) {
		var EObject current = lType;
		while (current !== null && !(current instanceof LPackage)) {
			current = current.eContainer();
		}
		return current as LPackage;
	}

	def dispatch String toName(LFeature feature) {
		if(feature === null || feature.name === null) return ""
		return feature.name.replace("^", "")
	}

	def dispatch String toName(LClass clazz) {
		if (clazz === null || clazz.name === null) {
			return ""
		}
		return clazz.name.replace("^", "")
	}
	
	def String replaceCaret(String value) {
		if(value === null) {
			return value
		}
		return value.replace("^", "")
	}

	def dispatch String toName(LType clazz) {
		if (clazz === null || clazz.name === null) {
			return ""
		}
		return clazz.name.replace("^", "")
	}

	def toQualifiedName(LType type) {
		val LPackage pkg = type.getPackage
		if(pkg === null) {
			return ""
		}
		return pkg.name + "." + type.name
	}

	/**
	 * The binary <code>+</code> operator that concatenates two strings.
	 * 
	 * @param a
	 *            a string.
	 * @param b
	 *            another string.
	 * @return <code>a + b</code>
	 */
	def static String operator_plus(String a, String b) {
		return a.concat(b);
	}

	def String toDtoPackageName(LTypedPackage pkg) {
		if (pkg === null) {
			return "notDefined"
		}
		if (pkg.name.contains("entities")) {
			return pkg.name.replace("entities", "dtos")
		} else {
			return pkg.name + ".dtos"
		}
	}
}
