/**
 * 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 com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.osbp.dsl.common.xtext.extensions.ModelExtensions;
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.osbp.xtext.cubedsl.scoping.AbstractCubeDSLScopeProvider;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.Scopes;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Extension;

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation.html#scoping
 * on how and when to use it
 */
@SuppressWarnings("all")
public class CubeDSLScopeProvider extends AbstractCubeDSLScopeProvider {
  @Inject
  @Extension
  private ModelExtensions _modelExtensions;
  
  @Override
  public IScope getScope(final EObject context, final EReference reference) {
    boolean _equals = Objects.equal(reference, CubeDSLPackage.Literals.CUBE_DIMENSION_ENTITY_ENTITY__OVER_VALUE);
    if (_equals) {
      return this.getScope_CubeDimensionEntityEntityOverValue(((CubeDimensionEntityEntity) context));
    } else {
      boolean _equals_1 = Objects.equal(reference, CubeDSLPackage.Literals.CUBE_DIMENSION_USAGE__OVER_VALUE);
      if (_equals_1) {
        return this.getScope_CubeDimensionUsage_OverValue(((CubeDimensionUsage) context));
      } else {
        boolean _equals_2 = Objects.equal(reference, CubeDSLPackage.Literals.CUBE_MEASURE__MEASURE_COL);
        if (_equals_2) {
          return this.getScope_CubeMeasureCol(((CubeMeasure) context));
        } else {
          if (((((Objects.equal(reference, CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_COL_VALUE) || Objects.equal(reference, CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_NAME_COL_VALUE)) || Objects.equal(reference, CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_CAPTION_COL_VALUE)) || Objects.equal(reference, CubeDSLPackage.Literals.CUBE_LEVEL__LEVEL_ORDINAL_COL_VALUE)) || Objects.equal(reference, CubeDSLPackage.Literals.CUBE_LEVEL_PROP__LEVEL_PROP_COL_VALUE))) {
            return this.getScope_CubeEntityColRef(((EObject) context));
          } else {
            boolean _equals_3 = Objects.equal(reference, CubeDSLPackage.Literals.CUBE_ENTITY__KEY_VALUE);
            if (_equals_3) {
              return this.getScope_CubeEntity_KeyValue(((CubeEntity) context));
            } else {
              boolean _equals_4 = Objects.equal(reference, CubeDSLPackage.Literals.CUBE_DIMENSION_USAGE__SOURCE_VALUE);
              if (_equals_4) {
                return this.getScope_CubeDimensionUsage_SourceValue(((CubeDimensionUsage) context));
              } else {
                return super.getScope(context, reference);
              }
            }
          }
        }
      }
    }
  }
  
  public IScope getScope_CubeDimensionUsage_SourceValue(final CubeDimensionUsage cubeDimUsage) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    EObject eObj = cubeDimUsage.eContainer();
    while ((!(eObj instanceof CubePackage))) {
      eObj = eObj.eContainer();
    }
    CubePackage cubePackage = ((CubePackage) eObj);
    if ((cubePackage != null)) {
      EList<CubeDimension> _dimensions = cubePackage.getDimensions();
      for (final CubeDimension cubeDim : _dimensions) {
        String _name = cubeDim.getName();
        boolean _tripleNotEquals = (_name != null);
        if (_tripleNotEquals) {
          result.add(cubeDim);
        }
      }
    }
    return Scopes.scopeFor(result);
  }
  
  public IScope getScope_CubeDimensionUsage_OverValue(final CubeDimensionUsage cubeDimUsage) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    ArrayList<String> dimEntities = CollectionLiterals.<String>newArrayList();
    CubeDimension dimUsageSource = cubeDimUsage.getSourceValue();
    LEntity cubeEnt = this.getCubeEntity(cubeDimUsage);
    if ((dimUsageSource != null)) {
      EList<CubeHierarchy> _hierarchies = dimUsageSource.getHierarchies();
      for (final CubeHierarchy cubeHierarchy : _hierarchies) {
        dimEntities.add(this.getDimEntityName(cubeHierarchy));
      }
      boolean _isTypeTime = dimUsageSource.isTypeTime();
      if (_isTypeTime) {
        List<LEntityAttribute> _allAttributes = cubeEnt.getAllAttributes();
        for (final LEntityAttribute entityAttr : _allAttributes) {
          boolean _isDate = this.isDate(entityAttr);
          if (_isDate) {
            result.add(entityAttr);
          }
        }
      }
    }
    if ((cubeEnt != null)) {
      boolean _contains = dimEntities.contains(cubeEnt.getName());
      if (_contains) {
        List<LEntityAttribute> _allAttributes_1 = cubeEnt.getAllAttributes();
        for (final LEntityAttribute entityAttr_1 : _allAttributes_1) {
          result.add(entityAttr_1);
        }
      } else {
        List<LEntityReference> _allReferences = cubeEnt.getAllReferences();
        for (final LEntityReference entityRef : _allReferences) {
          boolean _contains_1 = dimEntities.contains(this.getTypeName(entityRef));
          if (_contains_1) {
            result.add(entityRef);
          }
        }
      }
    }
    return Scopes.scopeFor(result);
  }
  
  public ArrayList<EObject> getRefResultList(final LEntity cubeEnt, final ArrayList<EObject> result) {
    List<LEntityReference> _allReferences = cubeEnt.getAllReferences();
    for (final LEntityReference entityRef : _allReferences) {
      String _name = entityRef.getName();
      boolean _tripleNotEquals = (_name != null);
      if (_tripleNotEquals) {
        result.add(entityRef);
      }
    }
    return result;
  }
  
  public LEntity getCubeEntity(final EObject childEObj) {
    LEntity cubeEnt = null;
    EObject eObj = childEObj.eContainer();
    while ((!(eObj instanceof CubeTypeEntity))) {
      if ((eObj != null)) {
        eObj = eObj.eContainer();
      }
    }
    if ((eObj != null)) {
      cubeEnt = ((CubeTypeEntity) eObj).getEntityRef().getEntityValue();
    }
    return cubeEnt;
  }
  
  public IScope getScope_CubeMeasureCol(final CubeMeasure cubeMeasure) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    LEntity cubeEnt = this.getCubeEntity(cubeMeasure);
    if ((cubeEnt != null)) {
      if (((cubeMeasure.getAggregator() != null) && (cubeMeasure.getAggregator().equals(CubeAggregatorEnum.COUNT) || 
        cubeMeasure.getAggregator().equals(CubeAggregatorEnum.DSC)))) {
        result = this.getRefResultList(cubeEnt, result);
      } else {
        List<LEntityAttribute> _allAttributes = cubeEnt.getAllAttributes();
        for (final LEntityAttribute entityAttr : _allAttributes) {
          if (((((entityAttr.getType() != null) && entityAttr.getEntity().isNormalAttribute(entityAttr)) && 
            (entityAttr.getType() instanceof LDataType)) && this._modelExtensions.isNumericOrWrapperType(((LDataType) entityAttr.getType())))) {
            result.add(entityAttr);
          }
        }
      }
    }
    return Scopes.scopeFor(result);
  }
  
  public IScope getScope_CubeEntityColRef(final EObject context) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    EObject eObj = context;
    while ((!(((eObj instanceof CubeDimensionEntity) || (eObj instanceof CubeDimensionEntityEntity)) || (eObj instanceof CubeTypeEntity)))) {
      if ((eObj != null)) {
        eObj = eObj.eContainer();
      }
    }
    if ((eObj != null)) {
      LEntity cubeEnt = null;
      if ((eObj instanceof CubeDimensionEntityEntity)) {
        cubeEnt = ((CubeDimensionEntityEntity) eObj).getEntityRef().getEntityValue();
      } else {
        if ((eObj instanceof CubeDimensionEntity)) {
          cubeEnt = ((CubeDimensionEntity) eObj).getEntityRef().getEntityValue();
        } else {
          if ((eObj instanceof CubeTypeEntity)) {
            cubeEnt = ((CubeTypeEntity) eObj).getEntityRef().getEntityValue();
          }
        }
      }
      result = this.getAttrResultList(cubeEnt, result);
    }
    return Scopes.scopeFor(result);
  }
  
  public IScope getScope_CubeDimensionEntityEntityOverValue(final CubeDimensionEntityEntity cubeDimEntityEntity) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    EObject eObj = cubeDimEntityEntity.eContainer();
    while ((!(eObj instanceof CubeDimensionEntity))) {
      if ((eObj != null)) {
        eObj = eObj.eContainer();
      }
    }
    if ((eObj != null)) {
      if ((eObj instanceof CubeDimensionEntity)) {
        result = this.getJoinableRefsResultList(cubeDimEntityEntity, ((CubeDimensionEntity) eObj), result);
      }
    }
    return Scopes.scopeFor(result);
  }
  
  public IScope getScope_CubeEntity_KeyValue(final CubeEntity entity) {
    ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
    if ((entity != null)) {
      result = this.getAttrResultList(entity.getEntityValue(), result);
    }
    return Scopes.scopeFor(result);
  }
  
  public ArrayList<EObject> getJoinableRefsResultList(final CubeDimensionEntityEntity cubeDimEntityEntity, final CubeDimensionEntity entity, final ArrayList<EObject> result) {
    if (((((entity != null) && (entity.getEntityRef() != null)) && (entity.getEntityRef().getEntityValue() != null)) && 
      (entity.getEntityRef().getEntityValue().getName() != null))) {
      LEntity cubeEnt = entity.getEntityRef().getEntityValue();
      List<LEntityReference> _allReferences = cubeEnt.getAllReferences();
      for (final LEntityReference lEntRef : _allReferences) {
        if (((((cubeDimEntityEntity.getEntityRef() != null) && (cubeDimEntityEntity.getEntityRef().getEntityValue() != null)) && 
          (cubeDimEntityEntity.getEntityRef().getEntityValue().getName() != null)) && 
          cubeDimEntityEntity.getEntityRef().getEntityValue().getName().equals(lEntRef.getType().getName()))) {
          result.add(lEntRef);
        }
      }
    }
    return result;
  }
  
  public ArrayList<EObject> getAttrResultList(final LEntity cubeEnt, final ArrayList<EObject> result) {
    if ((cubeEnt != null)) {
      List<LEntityAttribute> _allAttributes = cubeEnt.getAllAttributes();
      for (final LEntityAttribute entityAttr : _allAttributes) {
        String _name = entityAttr.getName();
        boolean _tripleNotEquals = (_name != null);
        if (_tripleNotEquals) {
          result.add(entityAttr);
        }
      }
    }
    return result;
  }
  
  public ArrayList<EObject> getAllFeaturesResultList(final LEntity cubeEnt, final ArrayList<EObject> result) {
    if ((cubeEnt != null)) {
      List<LEntityFeature> _allFeatures = cubeEnt.getAllFeatures();
      for (final LEntityFeature entityFeature : _allFeatures) {
        String _name = entityFeature.getName();
        boolean _tripleNotEquals = (_name != null);
        if (_tripleNotEquals) {
          result.add(entityFeature);
        }
      }
    }
    return result;
  }
  
  public String getDimEntityName(final CubeHierarchy cubeHierarchy) {
    if (((((cubeHierarchy != null) && (cubeHierarchy.getCubeDimEntity() != null)) && 
      (cubeHierarchy.getCubeDimEntity().getEntityRef() != null)) && 
      (cubeHierarchy.getCubeDimEntity().getEntityRef().getEntityValue() != null))) {
      return cubeHierarchy.getCubeDimEntity().getEntityRef().getEntityValue().getName();
    }
    return null;
  }
  
  public String getTypeName(final LEntityReference entityRef) {
    if (((entityRef.getType().getName() != null) && (entityRef.getType().getName() != null))) {
      return entityRef.getType().getName();
    }
    return null;
  }
  
  public boolean isDate(final LEntityAttribute entityAttr) {
    return ((entityAttr.getType() instanceof LDataType) && ((LDataType) entityAttr.getType()).isDate());
  }
}
