/**
 * 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 com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.osbp.dsl.semantic.common.types.LEnum;
import org.eclipse.osbp.dsl.semantic.common.types.LEnumLiteral;
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.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.EntityMockEntityNestedAttribute;
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.osbp.xtext.entitymock.scoping.AbstractEntityMockDSLScopeProvider;
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.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * 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 EntityMockDSLScopeProvider extends AbstractEntityMockDSLScopeProvider {
  @Override
  public IScope getScope(final EObject context, final EReference reference) {
    IScope _xblockexpression = null;
    {
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_ARRAY_VALUE__ENUMERATION)) {
        return this.getScope_MockObjectEnum(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_ITEM_VALUE__DATAROW)) {
        return this.getScope_MockObjectEnumValue(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_REFERENCED_OBJECT_ATTRIBUTE__EMBEDDED)) {
        return this.getScope_MockObjectEmbed(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_REFERENCED_OBJECT_ATTRIBUTE__ATTRIBUTE)) {
        return this.getScope_MockObjectAttribute(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_OBJECT__ATTRIBUTE_REF)) {
        return this.getEntityAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY__ITERATOR)) {
        return this.getEntityAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_FILLER__ATTRIBUTE_REF)) {
        return this.getEntityAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION__ATTRIBUTE_REF)) {
        return this.getEntityAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION_PARAMETER__ATTRIBUTE_REF)) {
        return this.getNestedAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_FUNCTION_PARAMETER__NESTED_ATTRIBUTE)) {
        return this.getNestedAttributes(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_NESTED_ATTRIBUTE__ATTRIBUTE)) {
        return this.getNestedAttributesAttribute(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ENTITY_NESTED_ATTRIBUTE__REFERENCE)) {
        return this.getEntityReferences(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__ATTRIBUTE_REF)) {
        return this.getEntityReferences(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_OBJECT__ATTRIBUTE_REF)) {
        boolean _matched = false;
        if (context instanceof EntityMockAttributeByObject) {
          _matched=true;
          EObject _eContainer = ((EntityMockAttributeByObject)context).eContainer();
          return MapBasedScope.createScope(IScope.NULLSCOPE, 
            this.getEntityAttributes(((EntityMockEntity) _eContainer), null));
        }
        if (!_matched) {
          if (context instanceof EntityMockEntity) {
            _matched=true;
            return MapBasedScope.createScope(IScope.NULLSCOPE, 
              this.getEntityAttributes(((EntityMockEntity) context), null));
          }
        }
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_FILLER__ATTRIBUTE_REF)) {
        boolean _matched_1 = false;
        if (context instanceof EntityMockAttributeFiller) {
          _matched_1=true;
          EObject _eContainer = ((EntityMockAttributeFiller)context).eContainer();
          return MapBasedScope.createScope(IScope.NULLSCOPE, 
            this.getEntityAttributes(((EntityMockEntity) _eContainer), null));
        }
        if (!_matched_1) {
          if (context instanceof EntityMockEntities) {
            _matched_1=true;
            return MapBasedScope.createScope(IScope.NULLSCOPE, 
              this.getEntityAttributes(((EntityMockEntities) context), null));
          }
        }
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__ATTRIBUTE_REF)) {
        boolean _matched_2 = false;
        if (context instanceof EntityMockAttributeByReference) {
          _matched_2=true;
          EObject _eContainer = ((EntityMockAttributeByReference)context).eContainer();
          return MapBasedScope.createScope(IScope.NULLSCOPE, 
            this.getEntityAttributes(((EntityMockEntity) _eContainer), null));
        }
        if (!_matched_2) {
          if (context instanceof EntityMockEntities) {
            _matched_2=true;
            return MapBasedScope.createScope(IScope.NULLSCOPE, 
              this.getEntityAttributes(((EntityMockEntities) context), null));
          }
        }
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_ATTRIBUTE_BY_REFERENCE__MOCKED_ENTITY)) {
        return this.getScope_MockAttributeReferencedMockedEntity(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_OBJECT_RESOURCE_VALUE__RESOURCE_ATTRIBUTE)) {
        return this.getScope_MockAttributeResourceAttribute(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_BY_RESOURCE_ATTRIBUTE__RESOURCE_ATTRIBUTE)) {
        return this.getScope_MockEntityResourceAttribute(context);
      }
      if ((reference == EntityMockDSLPackage.Literals.ENTITY_MOCK_BY_RESOURCE_ATTRIBUTE__ATTRIBUTE_REF)) {
        return this.getEntityAttributes(context);
      }
      _xblockexpression = super.getScope(context, reference);
    }
    return _xblockexpression;
  }
  
  public LEntity getEntityRef(final EObject context) {
    EObject eObj = context;
    while (((eObj != null) && (!(eObj instanceof EntityMockEntity)))) {
      eObj = eObj.eContainer();
    }
    if ((eObj != null)) {
      return ((EntityMockEntity) eObj).getEntityRef();
    } else {
      return null;
    }
  }
  
  public IScope getNestedAttributesAttribute(final EObject context) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    LEntityReference reference = ((EntityMockEntityNestedAttribute) context).getReference();
    if (((reference != null) && (!Objects.equal(reference.getType(), null)))) {
      List<LEntityAttribute> _allAttributes = reference.getType().getAllAttributes();
      for (final LEntityAttribute a : _allAttributes) {
        result.add(EObjectDescription.create(a.getName(), a));
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  public IScope getNestedAttributes(final EObject context) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    LEntity entity = this.getEntityRef(context);
    if ((entity != null)) {
      List<LEntityFeature> _allFeatures = entity.getAllFeatures();
      for (final LEntityFeature f : _allFeatures) {
        boolean _matched = false;
        if (f instanceof LEntityAttribute) {
          _matched=true;
          result.add(EObjectDescription.create(((LEntityAttribute)f).getName(), f));
        }
        if (!_matched) {
          if (f instanceof LEntityReference) {
            _matched=true;
            result.add(EObjectDescription.create(((LEntityReference)f).getName(), f));
          }
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  public IScope getEntityAttributes(final EObject context) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    LEntity entity = this.getEntityRef(context);
    if ((entity != null)) {
      List<LEntityAttribute> _allAttributes = entity.getAllAttributes();
      for (final LEntityAttribute attr : _allAttributes) {
        result.add(EObjectDescription.create(attr.getName(), attr));
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  public IScope getEntityReferences(final EObject context) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    LEntity entity = this.getEntityRef(context);
    if ((entity != null)) {
      List<LEntityReference> _allReferences = entity.getAllReferences();
      for (final LEntityReference ref : _allReferences) {
        String _name = ref.getName();
        boolean _tripleNotEquals = (_name != null);
        if (_tripleNotEquals) {
          result.add(EObjectDescription.create(ref.getName(), ((LEntityReference) ref)));
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available entity attributes contained in EntityMockEntities and add them to result
   */
  public ArrayList<IEObjectDescription> getEntityAttributes(final EntityMockEntities mockEntities, final ArrayList<IEObjectDescription> result) {
    ArrayList<IEObjectDescription> iresult = result;
    if ((iresult == null)) {
      iresult = CollectionLiterals.<IEObjectDescription>newArrayList();
    }
    if ((mockEntities != null)) {
      EList<EntityMockEntity> _entities = mockEntities.getEntities();
      for (final EntityMockEntity mockEntity : _entities) {
        iresult = this.getEntityAttributes(mockEntity, iresult);
      }
    }
    return iresult;
  }
  
  /**
   * get all available entity attributes contained in EntityMockEntity and add them to result
   */
  public ArrayList<IEObjectDescription> getEntityAttributes(final EntityMockEntity mockEntity, final ArrayList<IEObjectDescription> result) {
    ArrayList<IEObjectDescription> iresult = result;
    if ((iresult == null)) {
      iresult = CollectionLiterals.<IEObjectDescription>newArrayList();
    }
    if ((mockEntity != null)) {
      iresult = this.getEntityAttributes(mockEntity.getEntityRef(), iresult);
    }
    return iresult;
  }
  
  /**
   * get all available entity attributes contained in LEntity and add them to result
   */
  public ArrayList<IEObjectDescription> getEntityAttributes(final LEntity entity, final ArrayList<IEObjectDescription> result) {
    ArrayList<IEObjectDescription> iresult = result;
    if ((iresult == null)) {
      iresult = CollectionLiterals.<IEObjectDescription>newArrayList();
    }
    if ((entity != null)) {
      List<LEntityAttribute> _allAttributes = entity.getAllAttributes();
      for (final LEntityAttribute attribute : _allAttributes) {
        String _name = attribute.getName();
        boolean _tripleNotEquals = (_name != null);
        if (_tripleNotEquals) {
          iresult.add(EObjectDescription.create(attribute.getName(), attribute));
        }
      }
    }
    return iresult;
  }
  
  /**
   * get all available mock objects and add them as an IScope
   */
  public IScope getScope_MockObjectEmbed(final EObject object) {
    final ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EntityMockReferencedObjectAttribute emroa = ((EntityMockReferencedObjectAttribute) null);
    if ((object instanceof EntityMockReferencedObjectAttribute)) {
      emroa = ((EntityMockReferencedObjectAttribute)object);
    }
    if ((object instanceof EntityMockAttributeByObject)) {
      emroa = ((EntityMockAttributeByObject)object).getReference();
    }
    EntityMockObject mockObject = emroa.getTemplate().getObject();
    this.getScope_MockObjectRecursiveEmbed(result, mockObject);
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available mock objects recursively and add them to result
   */
  public void getScope_MockObjectRecursiveEmbed(final List<IEObjectDescription> result, final EntityMockObject mockObject) {
    if ((mockObject != null)) {
      EList<IEntityMockObjectAttribute> _attributes = mockObject.getAttributes();
      for (final IEntityMockObjectAttribute attribute : _attributes) {
        if ((attribute instanceof EntityMockObjectEmbed)) {
          result.add(EObjectDescription.create(((EntityMockObjectEmbed)attribute).getName(), attribute));
          this.getScope_MockObjectRecursiveEmbed(result, ((EntityMockObjectEmbed)attribute).getObject());
        }
      }
    }
  }
  
  /**
   * get all available enumerations and attributes of a mock object recursively and add them as an IScope
   */
  public IScope getScope_MockObjectAttribute(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EntityMockReferencedObjectAttribute emroa = ((EntityMockReferencedObjectAttribute) null);
    if ((object instanceof EntityMockReferencedObjectAttribute)) {
      emroa = ((EntityMockReferencedObjectAttribute)object);
    }
    if ((object instanceof EntityMockAttributeByObject)) {
      emroa = ((EntityMockAttributeByObject)object).getReference();
    }
    EntityMockObject mockObject = emroa.getTemplate().getObject();
    boolean _isEmpty = emroa.getEmbedded().isEmpty();
    boolean _not = (!_isEmpty);
    if (_not) {
      mockObject = IterableExtensions.<EntityMockObjectEmbed>last(emroa.getEmbedded()).getObject();
    }
    if ((mockObject != null)) {
      EList<EntityMockObjectEnum> _enumerations = mockObject.getEnumerations();
      for (final EntityMockObjectEnum enumeration : _enumerations) {
        result.add(
          EObjectDescription.create(((EntityMockObjectEnum) enumeration).getName(), ((EntityMockObjectEnum) enumeration)));
      }
      EList<IEntityMockObjectAttribute> _attributes = mockObject.getAttributes();
      for (final IEntityMockObjectAttribute attribute : _attributes) {
        if ((attribute instanceof EntityMockObjectEmbed)) {
        } else {
          result.add(
            EObjectDescription.create(((IEntityMockObjectAttribute) attribute).getName(), ((IEntityMockObjectAttribute) attribute)));
        }
      }
      EList<EntityMockObjectFunction> _calculations = mockObject.getCalculations();
      for (final EntityMockObjectFunction calculation : _calculations) {
        result.add(
          EObjectDescription.create(((EntityMockObjectFunction) calculation).getName(), ((EntityMockObjectFunction) calculation)));
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available enumerations of a mock object and add them as an IScope
   */
  public IScope getScope_MockObjectEnum(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject mockObject = object.eContainer();
    if ((mockObject instanceof EntityMockObject)) {
      EList<EntityMockObjectEnum> _enumerations = ((EntityMockObject)mockObject).getEnumerations();
      for (final EntityMockObjectEnum objectEnum : _enumerations) {
        result.add(
          EObjectDescription.create(((EntityMockObjectEnum) objectEnum).getName(), ((EntityMockObjectEnum) objectEnum)));
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available enumeration values of a mock object enumeration and add them as an IScope
   */
  public IScope getScope_MockObjectEnumValue(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject mockValueItem = object;
    while (((!(mockValueItem instanceof EntityMockObjectArrayValue)) && (mockValueItem != null))) {
      mockValueItem = mockValueItem.eContainer();
    }
    if ((mockValueItem instanceof EntityMockObjectArrayValue)) {
      LEnum _usingResource = ((EntityMockObjectArrayValue)mockValueItem).getEnumeration().getUsingResource();
      if ((_usingResource instanceof EntityMockResource)) {
        LEnum _usingResource_1 = ((EntityMockObjectArrayValue)mockValueItem).getEnumeration().getUsingResource();
        final EntityMockResource resource = ((EntityMockResource) _usingResource_1);
        EList<EntityMockResourceDataRow> _datarows = resource.getDatarows();
        for (final EntityMockResourceDataRow datarow : _datarows) {
          result.add(
            EObjectDescription.create(((EntityMockResourceDataRow) datarow).getName(), ((EntityMockResourceDataRow) datarow)));
        }
      } else {
        final LEnum lenum = ((EntityMockObjectArrayValue)mockValueItem).getEnumeration().getUsingResource();
        EList<LEnumLiteral> _literals = lenum.getLiterals();
        for (final LEnumLiteral datarow_1 : _literals) {
          result.add(EObjectDescription.create(datarow_1.getName(), datarow_1));
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available mocked entities fitting the referencing entity attribute and add them as an IScope
   */
  public IScope getScope_MockAttributeReferencedMockedEntity(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EntityMockAttributeByReference attributeByReference = ((EntityMockAttributeByReference) null);
    if ((object instanceof EntityMockAttributeByReference)) {
      attributeByReference = ((EntityMockAttributeByReference)object);
    }
    if ((attributeByReference != null)) {
      LEntity requested_entityRef = attributeByReference.getAttributeRef().getType();
      if ((requested_entityRef != null)) {
        EObject mockEntities = object.eContainer();
        while (((!(mockEntities instanceof EntityMockEntities)) && (!Objects.equal(mockEntities, null)))) {
          mockEntities = mockEntities.eContainer();
        }
        if ((mockEntities instanceof EntityMockEntities)) {
          EList<EntityMockEntity> _entities = ((EntityMockEntities)mockEntities).getEntities();
          for (final EntityMockEntity mockEntity : _entities) {
            boolean _equals = requested_entityRef.equals(mockEntity.getEntityRef());
            if (_equals) {
              result.add(
                EObjectDescription.create(((EntityMockEntity) mockEntity).getName(), ((EntityMockEntity) mockEntity)));
            }
          }
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  /**
   * get all available enumeration values of a mock object enumeration and add them as an IScope
   */
  public IScope getScope_MockAttributeResourceAttribute(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject objectResourceValue = object;
    while (((!(objectResourceValue instanceof EntityMockObjectResourceValue)) && (objectResourceValue != null))) {
      objectResourceValue = objectResourceValue.eContainer();
    }
    if ((objectResourceValue instanceof EntityMockObjectResourceValue)) {
      LEnum _usingResource = ((EntityMockObjectResourceValue)objectResourceValue).getResourceEnum().getUsingResource();
      if ((_usingResource instanceof EntityMockResource)) {
        LEnum _usingResource_1 = ((EntityMockObjectResourceValue)objectResourceValue).getResourceEnum().getUsingResource();
        final EntityMockResource resource = ((EntityMockResource) _usingResource_1);
        EList<EntityMockResourceAttribute> _attributes = resource.getAttributes();
        for (final EntityMockResourceAttribute attribute : _attributes) {
          result.add(
            EObjectDescription.create(((EntityMockResourceAttribute) attribute).getName(), ((EntityMockResourceAttribute) attribute)));
        }
      } else {
        final LEnum lenum = ((EntityMockObjectResourceValue)objectResourceValue).getResourceEnum().getUsingResource();
        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
   */
  public IScope getScope_MockEntityResourceAttribute(final EObject object) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject mockEntity = object;
    while (((!(mockEntity instanceof EntityMockEntity)) && (mockEntity != null))) {
      mockEntity = mockEntity.eContainer();
    }
    if ((mockEntity instanceof EntityMockEntity)) {
      EList<EntityMockResourceAttribute> _attributes = ((EntityMockEntity)mockEntity).getByResource().getAttributes();
      for (final EntityMockResourceAttribute attribute : _attributes) {
        result.add(
          EObjectDescription.create(((EntityMockResourceAttribute) attribute).getName(), ((EntityMockResourceAttribute) attribute)));
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
}
