package jetbrains.mps.baseLanguage.checkedDots.generator.referenceUtils;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.baseLanguage.behavior.IVariableReference__BehaviorDescriptor;
import jetbrains.mps.baseLanguage.behavior.IParameter__BehaviorDescriptor;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.mps.openapi.language.SInterfaceConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SProperty;

public class ReferenceConversionHelper {

  public static String getRefOrConceptFunctionParamName(SNode node) {
    if (SNodeOperations.isInstanceOf(node, CONCEPTS.IVariableReference$C)) {
      return SPropertyOperations.getString(IVariableReference__BehaviorDescriptor.getVariable_idSORzhOpB6t.invoke(SNodeOperations.cast(node, CONCEPTS.IVariableReference$C)), PROPS.name$MnvL);
    } else if (SNodeOperations.isInstanceOf(node, CONCEPTS.ConceptFunctionParameter$Tk)) {
      return IParameter__BehaviorDescriptor.getParameterName_idhP8qAbK.invoke(SNodeOperations.cast(node, CONCEPTS.ConceptFunctionParameter$Tk));
    } else {
      throw new IllegalArgumentException("Unexpected concept " + SNodeOperations.getConcept(node).getName());
    }
  }
  public static Iterable<SNode> retrieveDescendentRefsAndConceptFunctionParams(SNode node) {
    final List<SNode> flowInterruptors = ReferenceConversionHelper.retrieveFlowInterruptors(node);

    return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, CONCEPTS.IVariableReference$C, false, new SAbstractConcept[]{})).union(ListSequence.fromList(SNodeOperations.getNodeDescendants(node, CONCEPTS.ConceptFunctionParameter$Tk, false, new SAbstractConcept[]{}))).where((ref) -> !(ListSequence.fromList(flowInterruptors).contains(SNodeOperations.getNodeAncestorWhereConceptInList(ref, new SAbstractConcept[]{CONCEPTS.IControlFlowInterrupter$Ra, CONCEPTS.IStatementListContainer$xz, CONCEPTS.IContainsStatementList$v9}, false, false))));
  }

  public static Iterable<SNode> retrieveDescendentRefs(SNode node) {
    final List<SNode> flowInterruptors = ReferenceConversionHelper.retrieveFlowInterruptors(node);

    return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, CONCEPTS.IVariableReference$C, false, new SAbstractConcept[]{})).where((ref) -> !(ListSequence.fromList(flowInterruptors).contains(SNodeOperations.getNodeAncestorWhereConceptInList(ref, new SAbstractConcept[]{CONCEPTS.IControlFlowInterrupter$Ra, CONCEPTS.IStatementListContainer$xz, CONCEPTS.IContainsStatementList$v9}, false, false))));
  }

  public static Iterable<SNode> retrieveDescendentMethodCalls(SNode node) {
    final List<SNode> flowInterruptors = ReferenceConversionHelper.retrieveFlowInterruptors(node);

    return ListSequence.fromList(SNodeOperations.getNodeDescendants(node, CONCEPTS.IMethodCall$M9, true, new SAbstractConcept[]{})).where((call) -> !(ListSequence.fromList(flowInterruptors).contains(SNodeOperations.getNodeAncestorWhereConceptInList(call, new SAbstractConcept[]{CONCEPTS.IControlFlowInterrupter$Ra, CONCEPTS.IStatementListContainer$xz, CONCEPTS.IContainsStatementList$v9}, false, false))));
  }

  private static List<SNode> retrieveFlowInterruptors(SNode node) {
    return SNodeOperations.getNodeDescendantsWhereConceptInList(node, new SAbstractConcept[]{CONCEPTS.IControlFlowInterrupter$Ra, CONCEPTS.IStatementListContainer$xz, CONCEPTS.IContainsStatementList$v9}, true, new SAbstractConcept[]{});
  }

  private static final class CONCEPTS {
    /*package*/ static final SInterfaceConcept IVariableReference$C = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xe34de34746464f2L, "jetbrains.mps.baseLanguage.structure.IVariableReference");
    /*package*/ static final SConcept ConceptFunctionParameter$Tk = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101c66e2c0bL, "jetbrains.mps.baseLanguage.structure.ConceptFunctionParameter");
    /*package*/ static final SInterfaceConcept IControlFlowInterrupter$Ra = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x7c8556154508e980L, "jetbrains.mps.baseLanguage.structure.IControlFlowInterrupter");
    /*package*/ static final SInterfaceConcept IStatementListContainer$xz = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11750ef8265L, "jetbrains.mps.baseLanguage.structure.IStatementListContainer");
    /*package*/ static final SInterfaceConcept IContainsStatementList$v9 = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x120237c2cebL, "jetbrains.mps.baseLanguage.structure.IContainsStatementList");
    /*package*/ static final SInterfaceConcept IMethodCall$M9 = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall");
  }

  private static final class PROPS {
    /*package*/ static final SProperty name$MnvL = MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name");
  }
}
