/**
 * 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.authorizationdsl.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.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference;
import org.eclipse.osbp.dsl.semantic.entity.LBean;
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LBeanReference;
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.authorizationdsl.AuthorizationDSLPackage;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBean;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBeanAttribute;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBeanReference;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBlipProcess;
import org.eclipse.osbp.xtext.authorizationdsl.RoleBlipUserTask;
import org.eclipse.osbp.xtext.authorizationdsl.RoleDto;
import org.eclipse.osbp.xtext.authorizationdsl.RoleDtoAttribute;
import org.eclipse.osbp.xtext.authorizationdsl.RoleDtoReference;
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntity;
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntityAttribute;
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntityReference;
import org.eclipse.osbp.xtext.authorizationdsl.scoping.AbstractAuthorizationDSLScopeProvider;
import org.eclipse.osbp.xtext.blip.Blip;
import org.eclipse.osbp.xtext.blip.BlipItem;
import org.eclipse.osbp.xtext.blip.BlipUserTask;
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;

@SuppressWarnings("all")
public class AuthorizationDSLScopeProvider extends AbstractAuthorizationDSLScopeProvider {
  @Override
  public IScope getScope(final EObject context, final EReference reference) {
    boolean _equals = Objects.equal(reference, AuthorizationDSLPackage.Literals.ROLE_BLIP_USER_TASK__USER_TASK);
    if (_equals) {
      return this.getScope_RoleBlipProcess_UserTask(((RoleBlipUserTask) context));
    } else {
      boolean _equals_1 = Objects.equal(reference, AuthorizationDSLPackage.Literals.ROLE_ENTITY_FEATURE__ENTITY_ATTRI_COL);
      if (_equals_1) {
        return this.getScope_RoleEntityAttribute(context);
      } else {
        boolean _equals_2 = Objects.equal(reference, AuthorizationDSLPackage.Literals.ROLE_BEAN_FEATURE__BEAN_ATTRI_COL);
        if (_equals_2) {
          return this.getScope_RoleEntityAttribute(context);
        } else {
          boolean _equals_3 = Objects.equal(reference, AuthorizationDSLPackage.Literals.ROLE_DTO_FEATURE__DTO_ATTRI_COL);
          if (_equals_3) {
            return this.getScope_RoleEntityAttribute(context);
          }
        }
      }
    }
    return super.getScope(context, reference);
  }
  
  public IScope getScope_RoleEntityAttribute(final EObject context) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    boolean _matched = false;
    if (context instanceof RoleEntityAttribute) {
      _matched=true;
      EObject _eContainer = ((RoleEntityAttribute)context).eContainer();
      LEntity entity = ((RoleEntity) _eContainer).getEntityRef();
      if ((entity != null)) {
        List<LEntityAttribute> _allAttributes = entity.getAllAttributes();
        for (final LEntityAttribute attr : _allAttributes) {
          String _name = attr.getName();
          boolean _tripleNotEquals = (_name != null);
          if (_tripleNotEquals) {
            result.add(EObjectDescription.create(attr.getName(), attr));
          }
        }
      }
    }
    if (!_matched) {
      if (context instanceof RoleEntityReference) {
        _matched=true;
        EObject _eContainer = ((RoleEntityReference)context).eContainer();
        LEntity entity = ((RoleEntity) _eContainer).getEntityRef();
        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(), ref));
            }
          }
        }
      }
    }
    if (!_matched) {
      if (context instanceof RoleBeanAttribute) {
        _matched=true;
        EObject _eContainer = ((RoleBeanAttribute)context).eContainer();
        LBean bean = ((RoleBean) _eContainer).getBeanRef();
        if ((bean != null)) {
          List<LBeanAttribute> _allAttributes = bean.getAllAttributes();
          for (final LBeanAttribute attr : _allAttributes) {
            String _name = attr.getName();
            boolean _tripleNotEquals = (_name != null);
            if (_tripleNotEquals) {
              result.add(EObjectDescription.create(attr.getName(), attr));
            }
          }
        }
      }
    }
    if (!_matched) {
      if (context instanceof RoleBeanReference) {
        _matched=true;
        EObject _eContainer = ((RoleBeanReference)context).eContainer();
        LBean bean = ((RoleBean) _eContainer).getBeanRef();
        if ((bean != null)) {
          List<LBeanReference> _allReferences = bean.getAllReferences();
          for (final LBeanReference ref : _allReferences) {
            String _name = ref.getName();
            boolean _tripleNotEquals = (_name != null);
            if (_tripleNotEquals) {
              result.add(EObjectDescription.create(ref.getName(), ref));
            }
          }
        }
      }
    }
    if (!_matched) {
      if (context instanceof RoleDtoAttribute) {
        _matched=true;
        EObject _eContainer = ((RoleDtoAttribute)context).eContainer();
        LDto dto = ((RoleDto) _eContainer).getDtoRef();
        if ((dto != null)) {
          List<LDtoAbstractAttribute> _attributes = dto.getAttributes();
          for (final LDtoAbstractAttribute attr : _attributes) {
            String _name = attr.getName();
            boolean _tripleNotEquals = (_name != null);
            if (_tripleNotEquals) {
              result.add(EObjectDescription.create(attr.getName(), attr));
            }
          }
        }
      }
    }
    if (!_matched) {
      if (context instanceof RoleDtoReference) {
        _matched=true;
        EObject _eContainer = ((RoleDtoReference)context).eContainer();
        LDto dto = ((RoleDto) _eContainer).getDtoRef();
        if ((dto != null)) {
          List<LDtoAbstractReference> _references = dto.getReferences();
          for (final LDtoAbstractReference ref : _references) {
            String _name = ref.getName();
            boolean _tripleNotEquals = (_name != null);
            if (_tripleNotEquals) {
              result.add(EObjectDescription.create(ref.getName(), ref));
            }
          }
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  public IScope getScope_RoleEntityReference(final RoleEntityReference roleEntityReference) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject _eContainer = roleEntityReference.eContainer();
    LEntity entity = ((RoleEntity) _eContainer).getEntityRef();
    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(), ref));
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
  
  public IScope getScope_RoleBlipProcess_UserTask(final RoleBlipUserTask roleBlipUserTask) {
    ArrayList<IEObjectDescription> result = CollectionLiterals.<IEObjectDescription>newArrayList();
    EObject _eContainer = roleBlipUserTask.eContainer();
    Blip process = ((RoleBlipProcess) _eContainer).getProcess();
    if ((process != null)) {
      EList<BlipItem> _items = process.getItems();
      for (final BlipItem item : _items) {
        if ((item instanceof BlipUserTask)) {
          result.add(EObjectDescription.create(((BlipUserTask)item).getName(), item));
        }
      }
    }
    return MapBasedScope.createScope(IScope.NULLSCOPE, result);
  }
}
