/**
 *                                                                            
 * 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.xtext.entitymock.scoping

import java.util.ArrayList
import java.util.List
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
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.xtext.entitymock.EntityMockAttributeByObject
import org.eclipse.osbp.xtext.entitymock.EntityMockAttributeByReference
import org.eclipse.osbp.xtext.entitymock.EntityMockAttributeFiller
import org.eclipse.osbp.xtext.entitymock.EntityMockDSLPackage
import org.eclipse.osbp.xtext.entitymock.EntityMockEntities
import org.eclipse.osbp.xtext.entitymock.EntityMockEntity
import org.eclipse.osbp.xtext.entitymock.EntityMockObject
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectArrayValue
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectEmbed
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectEnum
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectFunction
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectResourceValue
import org.eclipse.osbp.xtext.entitymock.EntityMockReferencedObjectAttribute
import org.eclipse.osbp.xtext.entitymock.EntityMockResource
import org.eclipse.osbp.xtext.entitymock.EntityMockResourceAttribute
import org.eclipse.osbp.xtext.entitymock.EntityMockResourceDataRow
import org.eclipse.osbp.xtext.entitymock.IEntityMockObjectAttribute
import org.eclipse.xtext.resource.EObjectDescription
import org.eclipse.xtext.resource.IEObjectDescription
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.MapBasedScope
import org.eclipse.osbp.xtext.entitymock.EntityMockEntityFunctionParameter
import org.eclipse.osbp.xtext.entitymock.EntityMockEntityFunction
import org.eclipse.osbp.xtext.entitymock.EntityMockEntityNestedAttribute

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation.html#scoping
 * on how and when to use it 
 * 
 */
class EntityMockDSLScopeProvider extends AbstractEntityMockDSLScopeProvider {
	override IScope getScope(EObject context, EReference reference) {
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_ARRAY_VALUE__ENUMERATION) {
			return getScope_MockObjectEnum(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_ITEM_VALUE__DATAROW) {
			return getScope_MockObjectEnumValue(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_REFERENCED_OBJECT_ATTRIBUTE__EMBEDDED) {
			return getScope_MockObjectEmbed(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_REFERENCED_OBJECT_ATTRIBUTE__ATTRIBUTE) {
			return getScope_MockObjectAttribute(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_OBJECT__ATTRIBUTE_REF) {
			return getEntityAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY__ITERATOR) {
			return getEntityAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_FILLER__ATTRIBUTE_REF) {
			return getEntityAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION__ATTRIBUTE_REF) {
			return getEntityAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION_PARAMETER__ATTRIBUTE_REF) {
			return getNestedAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION_PARAMETER__NESTED_ATTRIBUTE) {
			return getNestedAttributes(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_NESTED_ATTRIBUTE__ATTRIBUTE) {
			return getNestedAttributesAttribute(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_NESTED_ATTRIBUTE__REFERENCE) {
			return getEntityReferences(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__ATTRIBUTE_REF) {
			return getEntityReferences(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_OBJECT__ATTRIBUTE_REF) {
			switch context {
				EntityMockAttributeByObject: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context.eContainer as EntityMockEntity).getEntityAttributes(null))
				EntityMockEntity: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context as EntityMockEntity).getEntityAttributes(null))
			}
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_FILLER__ATTRIBUTE_REF) {
			switch context {
				EntityMockAttributeFiller: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context.eContainer as EntityMockEntity).getEntityAttributes(null))
				EntityMockEntities: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context as EntityMockEntities).getEntityAttributes(null))
			}
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__ATTRIBUTE_REF) {
			switch context {
				EntityMockAttributeByReference: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context.eContainer as EntityMockEntity).getEntityAttributes(null))
				EntityMockEntities: return MapBasedScope.createScope(IScope.NULLSCOPE,
					(context as EntityMockEntities).getEntityAttributes(null))
			}
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__MOCKED_ENTITY) {
			return getScope_MockAttributeReferencedMockedEntity(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_RESOURCE_VALUE__RESOURCE_ATTRIBUTE) {
			return getScope_MockAttributeResourceAttribute(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_BY_RESOURCE_ATTRIBUTE__RESOURCE_ATTRIBUTE) {
			return getScope_MockEntityResourceAttribute(context)
		}
		if (reference === EntityMockDSLPackage.Literals.ENTITY_MOCK_BY_RESOURCE_ATTRIBUTE__ATTRIBUTE_REF) {
			return getEntityAttributes(context)
		}
		super.getScope(context, reference)
	}

	def LEntity getEntityRef(EObject context) {
		var eObj = context
		while (eObj !== null && !(eObj instanceof EntityMockEntity)) {
			eObj = eObj.eContainer()
		}
		if (eObj !== null) {
			return (eObj as EntityMockEntity).entityRef
		} else {
			return null
		}

	}

	def IScope getNestedAttributesAttribute(EObject context) {
		var result = <IEObjectDescription>newArrayList
		var reference = (context as EntityMockEntityNestedAttribute).reference
		if (reference !== null && reference.type != null) {
			for (a : reference.type.allAttributes) {
				result.add(EObjectDescription.create(a.name, a))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def IScope getNestedAttributes(EObject context) {
		var result = <IEObjectDescription>newArrayList
		var entity = context.entityRef
		if (entity !== null) {
			for (f : entity.allFeatures) {
				switch (f) {
					LEntityAttribute:
						result.add(EObjectDescription.create(f.name, f))
					LEntityReference:
						result.add(EObjectDescription.create(f.name, f))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def IScope getEntityAttributes(EObject context) {
		var result = <IEObjectDescription>newArrayList
		var entity = context.entityRef
		if (entity !== null) {
			for (LEntityAttribute attr : entity.allAttributes) {
				result.add(EObjectDescription.create(attr.name, attr))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def IScope getEntityReferences(EObject context) {
		var result = <IEObjectDescription>newArrayList
		var entity = context.entityRef
		if (entity !== null) {
			for (LEntityReference ref : entity.allReferences) {
				if (ref.name !== null) {
					result.add(EObjectDescription.create(ref.name, (ref as LEntityReference)))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available entity attributes contained in EntityMockEntities and add them to result
	 */
	def ArrayList<IEObjectDescription> getEntityAttributes(EntityMockEntities mockEntities,
		ArrayList<IEObjectDescription> result) {
		var iresult = result
		if (iresult === null) {
			iresult = <IEObjectDescription>newArrayList
		}
		if (mockEntities !== null) {
			for (mockEntity : mockEntities.entities) {
				iresult = mockEntity.getEntityAttributes(iresult)
			}
		}
		return iresult
	}

	/**
	 * get all available entity attributes contained in EntityMockEntity and add them to result
	 */
	def ArrayList<IEObjectDescription> getEntityAttributes(EntityMockEntity mockEntity,
		ArrayList<IEObjectDescription> result) {
		var iresult = result
		if (iresult === null) {
			iresult = <IEObjectDescription>newArrayList
		}
		if (mockEntity !== null) {
			iresult = mockEntity.entityRef.getEntityAttributes(iresult)
		}
		return iresult
	}

	/**
	 * get all available entity attributes contained in LEntity and add them to result
	 */
	def ArrayList<IEObjectDescription> getEntityAttributes(LEntity entity, ArrayList<IEObjectDescription> result) {
		var iresult = result
		if (iresult === null) {
			iresult = <IEObjectDescription>newArrayList
		}
		if (entity !== null) {
			for (LEntityAttribute attribute : entity.allAttributes) {
				if (attribute.name !== null) {
					iresult.add(EObjectDescription.create(attribute.name, attribute))
				}
			}
		}
		return iresult
	}

	/**
	 * get all available mock objects and add them as an IScope
	 */
	def IScope getScope_MockObjectEmbed(EObject object) {
		val result = <IEObjectDescription>newArrayList
		var emroa = null as EntityMockReferencedObjectAttribute
		if (object instanceof EntityMockReferencedObjectAttribute) {
			emroa = object
		}
		if (object instanceof EntityMockAttributeByObject) {
			emroa = object.reference
		}
		var mockObject = emroa.template.object
//        emroa.embedded.forEach ([ embed | {
//            if  (embed.name !== null) {
//                result.add(EObjectDescription.create(embed.name, embed))
//            }
//        }])
		getScope_MockObjectRecursiveEmbed(result, mockObject)
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available mock objects recursively and add them to result
	 */
	def void getScope_MockObjectRecursiveEmbed(List<IEObjectDescription> result, EntityMockObject mockObject) {
		if (mockObject !== null) {
			for (attribute : mockObject.attributes) {
				if (attribute instanceof EntityMockObjectEmbed) {
					result.add(EObjectDescription.create(attribute.name, attribute))
					getScope_MockObjectRecursiveEmbed(result, attribute.object)
				}
			}
		}
	}

	/**
	 * get all available enumerations and attributes of a mock object recursively and add them as an IScope
	 */
	def IScope getScope_MockObjectAttribute(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var emroa = null as EntityMockReferencedObjectAttribute
		if (object instanceof EntityMockReferencedObjectAttribute) {
			emroa = object
		}
		if (object instanceof EntityMockAttributeByObject) {
			emroa = object.reference
		}
		var mockObject = emroa.template.object
		if (!emroa.embedded.isEmpty) {
			mockObject = emroa.embedded.last.object
		}
		if (mockObject !== null) {
			for (enumeration : mockObject.enumerations) {
				result.add(
					EObjectDescription.create((enumeration as EntityMockObjectEnum).name,
						(enumeration as EntityMockObjectEnum)))
			}
			for (attribute : mockObject.attributes) {
				if (attribute instanceof EntityMockObjectEmbed) {
					// getScope_MockObjectAttribute(prefix+(attribute as IEntityMockObjectAttribute).name+"_", attribute.object, result)
				} else {
					result.add(
						EObjectDescription.create((attribute as IEntityMockObjectAttribute).name,
							(attribute as IEntityMockObjectAttribute)))
				}
			}
			for (calculation : mockObject.calculations) {
				result.add(
					EObjectDescription.create((calculation as EntityMockObjectFunction).name,
						(calculation as EntityMockObjectFunction)))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available enumerations of a mock object and add them as an IScope
	 */
	def IScope getScope_MockObjectEnum(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var mockObject = object.eContainer
		if (mockObject instanceof EntityMockObject) {
			for (objectEnum : mockObject.enumerations) {
				result.add(
					EObjectDescription.create((objectEnum as EntityMockObjectEnum).name,
						(objectEnum as EntityMockObjectEnum)))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available enumeration values of a mock object enumeration and add them as an IScope
	 */
	def IScope getScope_MockObjectEnumValue(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var mockValueItem = object
		while (!(mockValueItem instanceof EntityMockObjectArrayValue) && (mockValueItem !== null)) {
			mockValueItem = mockValueItem.eContainer
		}
		if (mockValueItem instanceof EntityMockObjectArrayValue) {
			if (mockValueItem.enumeration.usingResource instanceof EntityMockResource) {
				val resource = mockValueItem.enumeration.usingResource as EntityMockResource
				for (datarow : resource.datarows) {
					result.add(
						EObjectDescription.create((datarow as EntityMockResourceDataRow).name,
							(datarow as EntityMockResourceDataRow)))
				}
			} else {
				val lenum = mockValueItem.enumeration.usingResource
				for (datarow : lenum.literals) {
					result.add(EObjectDescription.create(datarow.name, datarow))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available mocked entities fitting the referencing entity attribute and add them as an IScope
	 */
	def IScope getScope_MockAttributeReferencedMockedEntity(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var attributeByReference = null as EntityMockAttributeByReference
		if (object instanceof EntityMockAttributeByReference) {
			attributeByReference = object
		}
		if (attributeByReference !== null) {
			var requested_entityRef = attributeByReference.attributeRef.type
			if (requested_entityRef !== null) {
				var mockEntities = object.eContainer
				while (!(mockEntities instanceof EntityMockEntities) && (mockEntities != null)) {
					mockEntities = mockEntities.eContainer
				}
				if (mockEntities instanceof EntityMockEntities) {
					for (mockEntity : mockEntities.entities) {
						if (requested_entityRef.equals(mockEntity.entityRef)) {
							result.add(
								EObjectDescription.create((mockEntity as EntityMockEntity).name,
									(mockEntity as EntityMockEntity)))
						}
					}
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available enumeration values of a mock object enumeration and add them as an IScope
	 */
	def IScope getScope_MockAttributeResourceAttribute(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var objectResourceValue = object
		while (!(objectResourceValue instanceof EntityMockObjectResourceValue) && (objectResourceValue !== null)) {
			objectResourceValue = objectResourceValue.eContainer
		}
		if (objectResourceValue instanceof EntityMockObjectResourceValue) {
			if (objectResourceValue.resourceEnum.usingResource instanceof EntityMockResource) {
				val resource = objectResourceValue.resourceEnum.usingResource as EntityMockResource
				for (attribute : resource.attributes) {
					result.add(
						EObjectDescription.create((attribute as EntityMockResourceAttribute).name,
							(attribute as EntityMockResourceAttribute)))
				}
			} else {
				val lenum = objectResourceValue.resourceEnum.usingResource
				result.add(EObjectDescription.create("name", lenum))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	/**
	 * get all available enumeration values of a mock object enumeration and add them as an IScope
	 */
	def IScope getScope_MockEntityResourceAttribute(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var mockEntity = object
		while (!(mockEntity instanceof EntityMockEntity) && (mockEntity !== null)) {
			mockEntity = mockEntity.eContainer
		}
		if (mockEntity instanceof EntityMockEntity) {
			for (attribute : mockEntity.byResource.attributes) {
				result.add(
					EObjectDescription.create((attribute as EntityMockResourceAttribute).name,
						(attribute as EntityMockResourceAttribute)))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
}
