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

import com.google.inject.Inject
import java.util.List
import org.eclipse.emf.ecore.EObject
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
import org.eclipse.osbp.dsl.semantic.common.helper.Bounds
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute
import org.eclipse.osbp.dsl.semantic.common.types.LFeature
import org.eclipse.osbp.dsl.semantic.common.types.LReference
import org.eclipse.osbp.dsl.semantic.common.types.LType
import org.eclipse.osbp.dsl.semantic.dto.LDto
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference
import org.eclipse.osbp.dsl.semantic.dto.LDtoAttribute
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.dto.LDtoOperation
import org.eclipse.osbp.dsl.semantic.dto.LDtoReference
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute
import org.eclipse.osbp.dsl.semantic.entity.LBeanReference
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
import org.eclipse.osbp.dsl.semantic.service.LCardinality
import org.eclipse.osbp.dsl.semantic.service.LInjectedService

class ModelExtensions extends org.eclipse.osbp.dsl.common.xtext.extensions.ModelExtensions {

	@Inject extension IQualifiedNameProvider
	@Inject extension JvmTypesBuilder
	@Inject extension MethodNamingExtensions

	@Inject TypeReferences references;

	def dispatch JvmTypeReference toTypeReference(LDtoAbstractReference prop) {
		var JvmTypeReference jvmTypeRef = prop.toDtoTypeParameterReference
		return jvmTypeRef
	}

	def dispatch JvmTypeReference toTypeReference(LDtoAbstractAttribute prop) {
		var JvmTypeReference jvmTypeRef = prop.toDtoTypeParameterReference
		return jvmTypeRef
	}

	/**
	 * Creates a type references with respect to inherited features
	 */
	def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoAbstractReference prop) {

		// prop.type is instanceof DTO
		return prop.type?.toTypeReference.cloneWithProxies
	}

	/**
	 * Creates a type references with respect to inherited features
	 */
	def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoAbstractAttribute prop) {

		// prop.type is instanceof LDataType
		return prop.type?.toTypeReference.cloneWithProxies
	}

	/**
	 * Creates a type references with respect to inherited features
	 */
	def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoInheritedAttribute prop) {

		if (prop.type != null) {

			// if the type is a different one, then use the type of the property
			// needs to be mapped by a custom mapper in dsl
			return prop.type?.toTypeReference.cloneWithProxies
		}

		// creates a type reference for the inherited LDataType
		return prop.inheritedFeature?.toTypeReference.cloneWithProxies
	}

	/**
	 * Creates a type references with respect to inherited features
	 */
	def dispatch JvmTypeReference toDtoTypeParameterReference(LDtoInheritedReference prop) {

		// for inherited references, the dto type is specified -> So use it
		return prop.type?.toTypeReference.cloneWithProxies
	}

	/**
	 * Creates a type reference with respect to multiplicity
	 */
	def JvmTypeReference toDtoTypeParameterReferenceWithMultiplicity(LDtoFeature prop) {
		var ref = prop.toDtoTypeParameterReference
		if (ref != null && prop.bounds.toMany) {
			ref = references.getTypeForName(typeof(List), prop, ref)
		}
		return ref
	}

	/**
	 * Creates a type reference with respect to multiplicity
	 */
	def JvmTypeReference toRawTypeReferenceWithMultiplicity(LDtoFeature prop) {
		var ref = prop.toRawTypeRefernce;
		if (prop.bounds.toMany) {
			ref = references.getTypeForName(typeof(List), prop, ref)
		}
		return ref
	}

	def dispatch isCascading(LDtoOperation prop) {
		false
	}

	def LDtoAbstractReference getResolvedOpposite(LDtoReference prop) {

		// For a toMany that has already an opposite, return it.
		// Otherwise search in the referenced type for the property with the owner type.
		if (prop.opposite != null) {
			return prop.opposite
		} else if (prop.type instanceof LDto) {
			val LDto ref = prop.type as LDto
			ref.references.findFirst[it.opposite == prop]
		}
	}

	/**
   	 * Returns true, if toCheck can be cast to superType
   	 */
	def boolean isCastable(LDto toCheck, LDto superType) {
		val String toCheckFqn = toCheck.fullyQualifiedName.toString
		val String superTypeFqn = superType.fullyQualifiedName.toString

		if (toCheckFqn.equals(superTypeFqn)) {
			return true
		} else {
			val LDto toCheckSuperType = toCheck.getSuperType
			if (toCheckSuperType != null) {
				return toCheckSuperType.isCastable(superType)
			} else {
				return false;
			}
		}
	}

	def dispatch inherited(LFeature prop) {
		return false
	}

	def dispatch inherited(LDtoInheritedReference prop) {
		return true
	}

	def dispatch inherited(LDtoInheritedAttribute prop) {
		return true
	}

	/**
	 * 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) {
		if (a == null || b == null)
			return ""

		return a + b;
	}

	def dispatch String toTypeName(LDtoAttribute prop) {
		prop.type.name
	}

	def dispatch String toTypeName(LDtoInheritedAttribute prop) {
		if (prop.type != null) {
			prop.type.name
		} else {
			prop.inheritedFeature.^type.name
		}
	}

	def dispatch String toTypeName(LDtoReference prop) {
		prop.type?.name
	}

	def dispatch String toTypeName(LDtoInheritedReference prop) {
		prop.type?.name
	}

	def dispatch LType toRawType(LFeature prop) {
		throw new IllegalStateException("not a valid call")
	}

	def dispatch LType toRawType(LDtoAttribute prop) {
		prop.type
	}

	def dispatch LType toRawType(LDtoInheritedAttribute prop) {
		prop.inheritedFeature?.type
	}

	def dispatch LType toRawType(LDtoReference prop) {
		prop.type
	}

	def dispatch LType toRawType(LDtoInheritedReference prop) {
		prop.inheritedFeature?.toRawType
	}

	def dispatch LType toRawType(LEntityReference prop) {
		prop.type as LType
	}

	def dispatch LType toRawType(LEntityAttribute prop) {
		prop.type as LType
	}

	def dispatch LType toRawType(LBeanReference prop) {
		prop.type as LType
	}

	def dispatch LType toRawType(LBeanAttribute prop) {
		prop.type as LType
	}

	def toRawTypeRefernce(LDtoFeature prop) {
		prop.toRawType?.toTypeReference
	}

	def String toRawTypeName(LDtoFeature prop) {
		prop.toRawType?.name
	}

	def dispatch LReference opposite(LDtoFeature prop) {
		null
	}

	def dispatch LReference opposite(LDtoReference prop) {
		return prop.opposite
	}

	def dispatch LReference opposite(LDtoInheritedReference prop) {
		if (prop.inherited && prop.inheritedFeature != null) {
			return prop.inheritedFeature.opposite
		} else {
			return null
		}
	}

	def dispatch LReference opposite(LEntityReference prop) {
		prop.opposite as LReference
	}

	def dispatch LReference opposite(LBeanReference prop) {
		prop.opposite as LReference
	}

	def dispatch Bounds getBounds(LDtoFeature prop) {
		if (prop.inherited) {
			return Bounds.createFor(prop.inheritedFeature);
		} else {
			return Bounds.createFor(prop);
		}
	}

	def dispatch String toName(LDtoFeature feature) {
		if(feature == null || !feature.inherited && feature.name == null) return ""
		if (feature.inherited) {
			return feature.inheritedFeature?.toName
		}
		return feature.name.replace("^", "")
	}

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

	//	def dispatch String internalToName(LFeature prop) {
	//		return prop.name;
	//	}
	//
	//	def dispatch String internalToName(LDtoFeature prop) {
	//		if (prop.inherited) {
	//			return prop.inheritedFeature?.name;
	//		} else {
	//			return prop.name;
	//		}
	//	}
	def dispatch LReference inheritedFeature(LDtoFeature prop) {
		return null
	}

	def dispatch LReference inheritedFeature(LDtoInheritedReference prop) {
		return prop.inheritedFeature
	}

	def dispatch LAttribute inheritedFeature(LDtoInheritedAttribute prop) {
		return prop.inheritedFeature
	}

	override isToMany(LFeature prop) {
		if (prop == null) {
			return false
		}
		return internalIsToMany(prop);
	}

	def dispatch boolean isTransient(EObject context) {
		false
	}

	def dispatch boolean isTransient(LDtoAttribute context) {
		context.transient
	}

	def dispatch boolean internalIsToMany(LFeature prop) {
		return prop.bounds.toMany;
	}

	def dispatch boolean internalIsToMany(LDtoFeature prop) {
		if (prop.inherited && prop.inheritedFeature != null) {
			return prop.inheritedFeature.internalIsToMany
		} else {
			return prop.bounds.toMany;
		}
	}

	def dispatch boolean isCascading(LDtoAbstractReference prop) {
		if (prop.inherited && prop.inheritedFeature != null) {
			return prop.inheritedFeature.cascading
		} else {
			return prop.cascading;
		}
	}

	def dispatch boolean isCascading(LDtoAbstractAttribute prop) {
		if (prop.inherited && prop.inheritedFeature != null) {
			return prop.inheritedFeature.cascading
		} else {
			return prop.cascading;
		}
	}

	def isCrossReference(LDtoFeature prop) {
		return prop instanceof LReference && !prop.cascading
	}

	//	def dispatch boolean shouldUseCrossReference(LDtoFeature prop) {
	//
	//		//		if (prop.crossReference) {
	//		//			if (prop.inherited && prop.inheritedFeature != null) {
	//		//				return prop.inheritedFeature.shouldUseCrossReference
	//		//			} else {
	//		//				return true
	//		//			}
	//		//		}
	//		return false
	//	}
	//
	//	def dispatch boolean shouldUseCrossReference(LEntityReference prop) {
	//		if (prop.cascading) {
	//			return false
	//		}
	//
	//		if (prop.opposite == null) {
	//			return true
	//		}
	//
	//		if (prop.opposite.cascading) {
	//			return false
	//		}
	//		return true
	//	}
	def isMany(LInjectedService service) {
		return service.cardinality == LCardinality::ZERO_TO_MANY || service.cardinality == LCardinality::ONE_TO_MANY
	}

	def boolean basedOnEntity(LDto dto) {
		dto.wrappedType != null && dto.wrappedType instanceof LEntity
	}

	def Iterable<LDtoAbstractAttribute> collectAllAttributes(LDto dto) {
		return dto.allFeatures.filter[it instanceof LDtoAbstractAttribute].map[it as LDtoAbstractAttribute]
	}

	def LAttribute idAttribute(LDto dto) {
		for (LDtoAbstractAttribute prop : dto.collectAllAttributes) {
			if (prop.inherited && prop.inheritedFeature != null) {
				val LAttribute attribute = prop.inheritedFeature as LAttribute
				if (attribute.id || attribute.uuid) {
					return attribute
				}
			} else {
				if (prop.id || prop.uuid) {
					return prop
				}
			}
		}
	}

	def LEntity wrappedEntity(LDto dto) {
		if (dto.basedOnEntity) {
			return dto.wrappedType as LEntity
		}
		return null
	}

	def String wrappedEntityName(LDto dto) {
		val entity = dto.wrappedEntity
		if (entity != null) {
			return entity.name
		}
		return null
	}
}
