package jetbrains.mps.lang.structure.findUsages;

/*Generated by MPS */

import jetbrains.mps.ide.findusages.findalgorithm.finders.GeneratedFinder;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SearchScope;
import jetbrains.mps.ide.findusages.model.scopes.ModelsScope;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.ide.findusages.findalgorithm.finders.IFinder;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.ide.findusages.view.FindUtils;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.ide.findusages.model.SearchQuery;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;

public class ConceptDescendants_Finder extends GeneratedFinder {
  public ConceptDescendants_Finder() {
  }
  public boolean isVisible(SNode node, SearchScope scope) {
    return false;
  }
  @Override
  public boolean isVisible(SNode node) {
    return isVisible(node, new ModelsScope(node.getModel()));
  }
  @Override
  public String getDescription() {
    return "Concept Descendants";
  }
  @Override
  public String getLongDescription() {
    return "Merging the inheriting logic for interface concepts and for concepts";
  }
  @Override
  public SAbstractConcept getSConcept() {
    return CONCEPTS.AbstractConceptDeclaration$KA;
  }

  @Override
  protected void doFind0(@NotNull SNode node, SearchScope scope, final IFinder.FindCallback callback, final ProgressMonitor monitor) {
    monitor.start(getDescription(), 2);
    try {
      boolean isIntfc = SNodeOperations.isInstanceOf(node, CONCEPTS.InterfaceConceptDeclaration$CG);
      if (isIntfc) {
        FindUtils.searchForResults(monitor.subTask(1), (searchResult) -> {
          SNode nodeParam = (SNode) searchResult.getObject();
          ((_FunctionTypes._void_P1_E0<SNode>) (SNode concept) -> {
            if (monitor.isCanceled()) {
              return;
            }
            callback.onUsageFound(createSingleResult(concept));
          }).invoke(nodeParam);
        }, new SearchQuery(node, scope), FindUtils.getFinder("jetbrains.mps.lang.structure.findUsages.ImplementingConcepts_Finder"), FindUtils.getFinder("jetbrains.mps.lang.structure.findUsages.DerivedInterfaceConcepts_Finder"));
      } else {
        FindUtils.searchForResults(monitor.subTask(1), (searchResult) -> {
          SNode nodeParam = (SNode) searchResult.getObject();
          ((_FunctionTypes._void_P1_E0<SNode>) (SNode concept) -> {
            if (monitor.isCanceled()) {
              return;
            }
            callback.onUsageFound(createSingleResult(concept));
          }).invoke(nodeParam);
        }, new SearchQuery(node, scope), FindUtils.getFinder("jetbrains.mps.lang.structure.findUsages.DerivedConcepts_Finder"));
      }
    } finally {
      monitor.done();
    }
  }


  @Nullable
  @Override
  public SNodeReference getDeclarationNode() {
    return buildNodePointer(FindUsagesDescriptor.DECLARING_MODEL, "2707675432437255202");
  }

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