/**
 *                                                                            
 * 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 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:   
 * 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.emf.ecore.InternalEObject
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.common.types.impl.JvmParameterizedTypeReferenceImpl
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import javax.inject.Inject
import org.eclipse.osbp.dsl.common.xtext.extensions.ModelExtensions

/**
 * 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*/ {
	@Inject extension ModelExtensions
	
	@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__LEVEL_NAME_COL_VALUE) ||
			(reference == CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_CAPTION_COL_VALUE) ||
			(reference == CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_ORDINAL_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 = null;
		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.entity.isNormalAttribute(entityAttr) &&
						entityAttr.type instanceof LDataType && isNumericOrWrapperType(entityAttr.type as LDataType)) {
						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)
		}
	}
	