package jetbrains.mps.smodel.search;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import jetbrains.mps.scope.Scope;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.util.Condition;
import jetbrains.mps.util.SNodeOperations;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodIdV2;
import org.jetbrains.mps.openapi.model.SNodeUtil;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;

@GeneratedClass(node = "r:22db907b-8239-4180-8797-e91cea0b9573(jetbrains.mps.smodel.search)/8484262519286281120", model = "r:22db907b-8239-4180-8797-e91cea0b9573(jetbrains.mps.smodel.search)")
public class ConceptAndSuperConceptsScope extends Scope {
  private final SNode myTopConcept;

  public ConceptAndSuperConceptsScope(@Nullable SNode topConcept) {
    myTopConcept = topConcept;
  }

  @Override
  public SNode resolve(SNode anchor, String refText) {
    // [MM] left intact, change if needed
    return null;
  }

  @Override
  public Iterable<SNode> getAvailableElements(@Nullable final String prefix) {
    if ((prefix == null || prefix.length() == 0)) {
      return getNodes(null);
    }
    return getNodes(new Condition<SNode>() {
      @Override
      public boolean met(SNode p0) {
        if (p0 == null) {
          return false;
        }
        String presentation = getReferenceText(null, p0);
        return presentation != null && presentation.startsWith(prefix);
      }
    });
  }

  @Override
  public String getReferenceText(SNode anchor, SNode target) {
    String resolveInfo = SNodeOperations.getResolveInfo(target);
    if ((resolveInfo != null && resolveInfo.length() > 0)) {
      return resolveInfo;
    }
    return target.getPresentation();
  }

  @NotNull
  public List<SNode> getNodes(@Nullable Condition<SNode> condition) {
    if (myTopConcept == null) {
      return Collections.<SNode>emptyList();
    }
    List<SNode> result = new ArrayList<SNode>();
    for (SNode node : ((Iterable<SNode>) BHReflection.invoke0(myTopConcept, CONCEPTS.AbstractConceptDeclaration$KA, SMethodIdV2.create("getAllSuperConcepts", 2992811758677902956L, 0x44a456bea0df1cf0L), ((boolean) true)))) {
      // FIXME why do we collect *all* children, including InterfaceConceptReference of implements/extends, ACD.helpURL and CD.icon?
      // I suppose all we need here is linkDeclaration + propertyDeclaration, both available in node<ACD> we've got here
      for (SNode n : SNodeUtil.getDescendants(node, condition, true)) {
        result.add(n);
      }
    }
    return result;
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept AbstractConceptDeclaration$KA = MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x1103553c5ffL, "jetbrains.mps.lang.structure.structure.AbstractConceptDeclaration");
  }
}
