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

import java.util.ArrayList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.osbp.dsl.semantic.common.types.LDataType
import org.eclipse.osbp.dsl.semantic.entity.LEntity
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference
import org.eclipse.osbp.xtext.cubedsl.CubeAggregatorEnum
import org.eclipse.osbp.xtext.cubedsl.CubeDSLPackage
import org.eclipse.osbp.xtext.cubedsl.CubeDimension
import org.eclipse.osbp.xtext.cubedsl.CubeDimensionEntity
import org.eclipse.osbp.xtext.cubedsl.CubeDimensionEntityEntity
import org.eclipse.osbp.xtext.cubedsl.CubeDimensionUsage
import org.eclipse.osbp.xtext.cubedsl.CubeEntity
import org.eclipse.osbp.xtext.cubedsl.CubeHierarchy
import org.eclipse.osbp.xtext.cubedsl.CubeMeasure
import org.eclipse.osbp.xtext.cubedsl.CubePackage
import org.eclipse.osbp.xtext.cubedsl.CubeTypeEntity
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation.html#scoping
 * on how and when to use it 
 * 
 */
//class CubeDSLScopeProvider extends AbstractDeclarativeScopeProvider {
class CubeDSLScopeProvider extends AbstractCubeDSLScopeProvider /*XbaseWithAnnotationsScopeProvider*/ {

	@Override
	override IScope getScope(EObject context, EReference reference) {
		if (reference == CubeDSLPackage.Literals.CUBE_DIMENSION_ENTITY_ENTITY__OVER_VALUE) {
			return getScope_CubeDimensionEntityEntityOverValue(context as CubeDimensionEntityEntity)
		} else if (reference == CubeDSLPackage.Literals.CUBE_DIMENSION_USAGE__OVER_VALUE) {
			return getScope_CubeDimensionUsage_OverValue(context as CubeDimensionUsage)
		} else if (reference == CubeDSLPackage.Literals.CUBE_MEASURE__MEASURE_COL) {
			return getScope_CubeMeasureCol(context as CubeMeasure)
		} else if ((reference == CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_COL_VALUE) ||
			(reference == CubeDSLPackage.Literals.CUBE_LEVEL_PROP__LEVEL_PROP_COL_VALUE)) {
			return getScope_CubeEntityColRef(context as EObject)
		} else if (reference == CubeDSLPackage.Literals.CUBE_ENTITY__KEY_VALUE) {
			return getScope_CubeEntity_KeyValue(context as CubeEntity)
		} else if (reference == CubeDSLPackage.Literals.CUBE_DIMENSION_USAGE__SOURCE_VALUE) {
			return getScope_CubeDimensionUsage_SourceValue(context as CubeDimensionUsage)
		} else {
			return super.getScope(context, reference)
		}

	}

	def IScope getScope_CubeDimensionUsage_SourceValue(CubeDimensionUsage cubeDimUsage) {
		var result = <EObject>newArrayList
		var eObj = cubeDimUsage.eContainer
		while (!(eObj instanceof CubePackage)) {
			eObj = eObj.eContainer
		}
		var cubePackage = (eObj as CubePackage)
		if (cubePackage !== null) {
			for (CubeDimension cubeDim : cubePackage.dimensions) {
				if (cubeDim.name !== null) {
					result.add(cubeDim)
				}
			}
		}
		return Scopes.scopeFor(result)
	}

	def getScope_CubeDimensionUsage_OverValue(CubeDimensionUsage cubeDimUsage) {
		var result = <EObject>newArrayList
		var dimEntities = <String>newArrayList
		var dimUsageSource = cubeDimUsage.getSourceValue
		var LEntity cubeEnt = cubeDimUsage.getCubeEntity
		if (dimUsageSource !== null) {
			for (CubeHierarchy cubeHierarchy : dimUsageSource.hierarchies) {
				dimEntities.add(cubeHierarchy.dimEntityName)
			}
			if (dimUsageSource.typeTime) {
				for (LEntityAttribute entityAttr : cubeEnt.allAttributes) {
					if (entityAttr.date) {
						result.add(entityAttr)
					}
				}
			}
		}
		if (cubeEnt !== null) {
			// If the cube entity is as the used entity for the dimension
			// only its attributes are used as foreign key 
			if (dimEntities.contains(cubeEnt.name)) {
				for (LEntityAttribute entityAttr : cubeEnt.allAttributes) {
					result.add(entityAttr)
				}
			} else {
				for (LEntityReference entityRef : cubeEnt.allReferences) {
					if (dimEntities.contains(entityRef.getTypeName)) {
						result.add(entityRef)
					}
				}
			}
		}
		return Scopes.scopeFor(result)
	}

	def ArrayList<EObject> getRefResultList(LEntity cubeEnt, ArrayList<EObject> result) {
		for (LEntityReference entityRef : cubeEnt.allReferences) {
			if (entityRef.name !== null) {
				result.add(entityRef)
			}
		}
		return result
	}

	def getCubeEntity(EObject childEObj) {
		var LEntity cubeEnt;
		var eObj = childEObj.eContainer
		while (!(eObj instanceof CubeTypeEntity)) {
			if (eObj !== null) {
				eObj = eObj.eContainer
			}
		}
		if (eObj !== null) {
			cubeEnt = (eObj as CubeTypeEntity).entityRef.entityValue
		}
		return cubeEnt
	}

	def getScope_CubeMeasureCol(CubeMeasure cubeMeasure) {
		var result = <EObject>newArrayList
		var LEntity cubeEnt = cubeMeasure.getCubeEntity
		if (cubeEnt !== null) {
			// if measure uses count aggregator only numeric entity attributes are provided
			if (cubeMeasure.aggregator !== null &&
				(cubeMeasure.aggregator.equals(CubeAggregatorEnum.COUNT) ||
					cubeMeasure.aggregator.equals(CubeAggregatorEnum.DSC))) {
				result = cubeEnt.getRefResultList(result)
			} else {
				for (LEntityAttribute entityAttr : cubeEnt.allAttributes) {
					if (entityAttr.type !== null && (entityAttr.type instanceof LDataType) &&
						(entityAttr.type as LDataType).asPrimitive &&
						!("String".equals((entityAttr.type as LDataType).name))) {
						result.add(entityAttr)
					}
				}
			}
		}
		return Scopes.scopeFor(result)
	}

	def IScope getScope_CubeEntityColRef(EObject context) {
		var result = <EObject>newArrayList
		var eObj = context
		while (!((eObj instanceof CubeDimensionEntity) || (eObj instanceof CubeDimensionEntityEntity) ||
			(eObj instanceof CubeTypeEntity))) {
			if (eObj !== null) {
				eObj = eObj.eContainer
			}
		}
		if (eObj !== null) {
			var LEntity cubeEnt = null;
			if (eObj instanceof CubeDimensionEntityEntity) {
				cubeEnt = (eObj as CubeDimensionEntityEntity).entityRef.entityValue
			} else if (eObj instanceof CubeDimensionEntity) {
				cubeEnt = (eObj as CubeDimensionEntity).entityRef.entityValue
			} else if (eObj instanceof CubeTypeEntity) {
				cubeEnt = (eObj as CubeTypeEntity).entityRef.entityValue
			}
			result = cubeEnt.getAttrResultList(result)
		}
		return Scopes.scopeFor(result)
	}

	def IScope getScope_CubeDimensionEntityEntityOverValue(CubeDimensionEntityEntity cubeDimEntityEntity) {
		var result = <EObject>newArrayList
		var eObj = cubeDimEntityEntity.eContainer
		while (!(eObj instanceof CubeDimensionEntity)) {
			if (eObj !== null) {
				eObj = eObj.eContainer
			}
		}
		if (eObj !== null) {
			if (eObj instanceof CubeDimensionEntity) {
				result = cubeDimEntityEntity.getJoinableRefsResultList((eObj as CubeDimensionEntity), result)
			}
		}
		return Scopes.scopeFor(result)
	}

	def IScope getScope_CubeEntity_KeyValue(CubeEntity entity) {
		var result = <EObject>newArrayList
		if (entity !== null) {
			result = entity.entityValue.getAttrResultList(result)
		}
		return Scopes.scopeFor(result)
	}

	def getJoinableRefsResultList(CubeDimensionEntityEntity cubeDimEntityEntity, CubeDimensionEntity entity,
		ArrayList<EObject> result) {
		if (entity !== null && entity.entityRef !== null && entity.entityRef.entityValue !== null &&
			entity.entityRef.entityValue.name !== null) {
			var LEntity cubeEnt = entity.entityRef.entityValue
			for (LEntityReference lEntRef : cubeEnt.allReferences) {
				if (cubeDimEntityEntity.entityRef !== null && cubeDimEntityEntity.entityRef.entityValue !== null &&
					cubeDimEntityEntity.entityRef.entityValue.name !== null &&
					cubeDimEntityEntity.entityRef.entityValue.name.equals(lEntRef.type.name)) {
					result.add(lEntRef)
				}
			}
		}
		return result;
	}

	def getAttrResultList(LEntity cubeEnt, ArrayList<EObject> result) {
		if (cubeEnt !== null) {
			for (LEntityAttribute entityAttr : cubeEnt.allAttributes) {
				if (entityAttr.name !== null) {
					result.add(entityAttr)
				}
			}
		}
		return result;
	}

	def getAllFeaturesResultList(LEntity cubeEnt, ArrayList<EObject> result) {
		if (cubeEnt !== null) {
			for (LEntityFeature entityFeature : cubeEnt.allFeatures) {
				if (entityFeature.name !== null) {
					result.add(entityFeature)
				}
			}
		}
		return result;
	}

	def getDimEntityName(CubeHierarchy cubeHierarchy) {
		if (cubeHierarchy !== null && cubeHierarchy.cubeDimEntity !== null &&
			cubeHierarchy.cubeDimEntity.entityRef !== null &&
			cubeHierarchy.cubeDimEntity.entityRef.entityValue !== null) {
				return cubeHierarchy.cubeDimEntity.entityRef.entityValue.name
			}
		}

		def getTypeName(LEntityReference entityRef) {
			if (entityRef.type.name !== null && entityRef.type.name !== null) {
				return entityRef.type.name
			}
		}

		def isDate(LEntityAttribute entityAttr) {
			return (entityAttr.type instanceof LDataType && (entityAttr.type as LDataType).date)
		}
	}
	