package jetbrains.mps.lang.intentions.intentions;

/*Generated by MPS */

import jetbrains.mps.editor.intentions.IntentionsFactory;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.smodel.SNodePointer;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.List;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.baseLanguage.lightweightdsl.behavior.DSLClassMember__BehaviorDescriptor;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import java.util.Collection;
import jetbrains.mps.editor.intentions.NodeTransformer;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import java.util.ArrayList;
import jetbrains.mps.editor.intentions.BaseNodeTransformer;
import jetbrains.mps.smodel.builder.SNodeBuilder;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import org.jetbrains.mps.openapi.language.SReferenceLink;
import org.jetbrains.mps.openapi.language.SProperty;

public class ConvertIntention extends IntentionsFactory {
  public ConvertIntention() {
  }

  public String getId() {
    return getClass().getName();
  }

  public boolean isAvailableInChildren() {
    return true;
  }

  public boolean isSurroundWith() {
    return false;
  }

  public SAbstractConcept getApplicableConcept() {
    return CONCEPTS.IntentionDeclaration$q4;
  }

  public SNodePointer getDeclarationNode() {
    return implementationNode;
  }

  private SNodePointer implementationNode = new SNodePointer("r:5a8e1e6d-7386-4281-8e53-bda28bd8edf3(jetbrains.mps.lang.intentions.intentions)", "7271443492838023362");


  private boolean isApplicableHelper(SNode node, EditorContext editorContext) {
    return ListSequence.fromList(SLinkOperations.getChildren(node, LINKS.fieldDeclaration$sOzg)).isEmpty() && ListSequence.fromList(SLinkOperations.getChildren(node, LINKS.methodDeclaration$ydlK)).isEmpty();
  }


  public boolean isAvailableInChild(SNode node, SNode node1, EditorContext context) {
    return false;
  }

  public boolean isApplicable(SNode node, EditorContext editorContext) {
    return isApplicableHelper(node, editorContext);
  }


  public void copyFunctionBody(SNode from, SNode to) {
    ListSequence.fromList(SLinkOperations.getChildren(SLinkOperations.getTarget(to, LINKS.body$5xQk), LINKS.statement$53DE)).addSequence(ListSequence.fromList(SLinkOperations.getChildren(from, LINKS.statement$53DE)).select((it) -> SNodeOperations.copyNode(it)));
  }
  public SNode createParameterReference(List<SNode> parameters, int argumentNumber) {
    SNode nodeRef = SNodeFactoryOperations.createNewNode(CONCEPTS.VariableReference$TC, null);
    SLinkOperations.setTarget(nodeRef, LINKS.variableDeclaration$N1XG, ListSequence.fromList(parameters).getElement(argumentNumber));
    return nodeRef;
  }
  public void resolveChildFilterRefernce(SNode root, SNode node) {
    SAbstractConcept cncpt = SNodeOperations.getConcept(node);
    boolean noneMatched = true;
    if (noneMatched && SConceptOperations.isSubConceptOf(cncpt, CONCEPTS.ConceptFunctionParameter_node$Gy)) {
      noneMatched = false;
      SNodeOperations.replaceWithAnother(node, createParameterReference(SLinkOperations.getChildren(root, LINKS.parameter$5xBj), 0));
    }
    if (noneMatched && SConceptOperations.isSubConceptOf(cncpt, CONCEPTS.ConceptFunctionParameter_childNode$qh)) {
      noneMatched = false;
      SNodeOperations.replaceWithAnother(node, createParameterReference(SLinkOperations.getChildren(root, LINKS.parameter$5xBj), 1));
    }
    if (noneMatched && SConceptOperations.isSubConceptOf(cncpt, CONCEPTS.ConceptFunctionParameter_editorContext$eI)) {
      noneMatched = false;
      SNodeOperations.replaceWithAnother(node, createParameterReference(SLinkOperations.getChildren(root, LINKS.parameter$5xBj), 2));
    }

    for (SNode child : SNodeOperations.getChildren(node)) {
      resolveChildFilterRefernce(root, child);
    }
  }
  public void resolveReference(SNode root, SNode node) {
    if (SConceptOperations.isExactly(SNodeOperations.asSConcept(SNodeOperations.getConcept(node)), CONCEPTS.ConceptFunctionParameter_node$Gy)) {
      SNodeOperations.replaceWithAnother(node, createParameterReference(SLinkOperations.getChildren(root, LINKS.parameter$5xBj), 0));
    } else if (SConceptOperations.isExactly(SNodeOperations.asSConcept(SNodeOperations.getConcept(node)), CONCEPTS.ConceptFunctionParameter_editorContext$eI)) {
      SNodeOperations.replaceWithAnother(node, createParameterReference(SLinkOperations.getChildren(root, LINKS.parameter$5xBj), 1));
    }

    for (SNode child : SNodeOperations.getChildren(node)) {
      resolveReference(root, child);
    }
  }
  public void execute(SNode node, EditorContext editorContext) {
    boolean oldIsErrorIntention = SPropertyOperations.getBoolean(node, PROPS.isErrorIntention$Mcvw);
    boolean oldIsAvailableInChildNodes = SPropertyOperations.getBoolean(node, PROPS.isAvailableInChildNodes$McIx);
    SNode oldExecute = SLinkOperations.getTarget(SLinkOperations.getTarget(node, LINKS.executeFunction$zyVM), LINKS.body$e68K);
    SNode oldDescription = SLinkOperations.getTarget(SLinkOperations.getTarget(node, LINKS.descriptionFunction$xRc1), LINKS.body$e68K);
    SNode oldIsApplicable = SLinkOperations.getTarget(SLinkOperations.getTarget(node, LINKS.isApplicableFunction$xRE3), LINKS.body$e68K);
    SNode oldChildFilter = SLinkOperations.getTarget(SNodeOperations.cast(SLinkOperations.getTarget(node, LINKS.childFilterFunction$xRr2), CONCEPTS.ChildFilterFunction$q_), LINKS.body$e68K);

    // create new intention
    SNode newIntention = SNodeFactoryOperations.createNewNode(CONCEPTS.Intention$zo, null);

    // obtain references to members

    SNode newExecute = SNodeOperations.cast(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.find_id2gzehMfi1$l.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7538218632063981347"), newIntention)).first(), CONCEPTS.MethodInstance$jE);
    SNode newDescription = SNodeOperations.cast(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.find_id2gzehMfi1$l.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7538218632063982514"), newIntention)).first(), CONCEPTS.MethodInstance$jE);

    if (oldIsAvailableInChildNodes) {
      SNodeOperations.replaceWithAnother(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.findPlaceholders_id5ZzANK5B6wZ.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7271443492837194032"), newIntention)).first(), DSLClassMember__BehaviorDescriptor.create_id7ay_HjIOVVe.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7271443492837194032"), SNodeOperations.getModel(node)));
      SNode newIsApplicableInChild = SNodeOperations.cast(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.find_id2gzehMfi1$l.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7271443492837194032"), newIntention)).first(), CONCEPTS.MethodInstance$jE);
      if ((oldChildFilter == null)) {
        ListSequence.fromList(SLinkOperations.getChildren(SLinkOperations.getTarget(newIsApplicableInChild, LINKS.body$5xQk), LINKS.statement$53DE)).addElement(_quotation_createNode_lf8yx8_a0a0a2a51a8());
      } else {
        copyFunctionBody(oldChildFilter, newIsApplicableInChild);
        resolveChildFilterRefernce(newIsApplicableInChild, newIsApplicableInChild);
      }
    }

    if ((SLinkOperations.getTarget(node, LINKS.isApplicableFunction$xRE3) != null)) {
      SNodeOperations.replaceWithAnother(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.findPlaceholders_id5ZzANK5B6wZ.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7538218632063982606"), newIntention)).first(), DSLClassMember__BehaviorDescriptor.create_id7ay_HjIOVVe.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7538218632063982606"), SNodeOperations.getModel(node)));
      SNode newIsApplicable = SNodeOperations.cast(Sequence.fromIterable(DSLClassMember__BehaviorDescriptor.find_id2gzehMfi1$l.invoke(SNodeOperations.getNode("r:d3905048-7598-4a84-931a-cbbcbcda146d(jetbrains.mps.lang.intentions.methods)", "7538218632063982606"), newIntention)).first(), CONCEPTS.MethodInstance$jE);

      copyFunctionBody(oldIsApplicable, newIsApplicable);
      resolveReference(newIsApplicable, newIsApplicable);
    }

    // set members
    SPropertyOperations.assign(newIntention, PROPS.name$MnvL, SPropertyOperations.getString(node, PROPS.name$MnvL));
    SLinkOperations.setTarget(newIntention, LINKS.forConcept$Mnu4, SLinkOperations.getTarget(node, LINKS.forConcept$zyGL));

    copyFunctionBody(oldDescription, newDescription);
    resolveReference(newDescription, newDescription);

    copyFunctionBody(oldExecute, newExecute);
    resolveReference(newExecute, newExecute);

    if (oldIsErrorIntention) {
      SLinkOperations.setTarget(newIntention, LINKS.priority$HQFL, SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x59427edd75744615L, "jetbrains.mps.lang.intentions.structure.ErrorIntentionPriority")));
    }


    SPropertyOperations.set(newIntention, PROPS.virtualPackage$EkXl, SPropertyOperations.getString(node, PROPS.virtualPackage$EkXl));
    SModelOperations.addRootNode(SNodeOperations.getModel(node), newIntention);
  }
  public String description(SNode node, EditorContext editorContext) {
    return "convert intention";
  }

  public Collection<NodeTransformer> getTreeTransformers(SNode node, SNode child, EditorContext editorContext) {
    Collection<NodeTransformer> result = CollectionSequence.fromCollection(new ArrayList<NodeTransformer>());
    CollectionSequence.fromCollection(result).addElement(new BaseNodeTransformer(this, node, editorContext, NodeTransformer.Kind.INTENTION, implementationNode) {
      protected void execute(SNode node, EditorContext editorContext) {
        ConvertIntention.this.execute(node, editorContext);
      }
      protected String getDescription(SNode node, EditorContext editorContext) {
        return ConvertIntention.this.description(node, editorContext);
      }
    });
    return result;
  }
  private static SNode _quotation_createNode_lf8yx8_a0a0a2a51a8() {
    SNode quotedNode_1 = null;
    SNode quotedNode_2 = null;
    SNodeBuilder nb = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf8cc67c7feL, "ReturnStatement"));
    quotedNode_1 = nb.getResult();
    SNodeBuilder nb1 = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf8cc56b201L, "BooleanConstant"));
    quotedNode_2 = nb1.getResult();
    nb1.setProperty(MetaAdapterFactory.getProperty(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b201L, 0xf8cc56b202L, "value"), "true");
    quotedNode_1.addChild(MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc67c7feL, 0xf8cc6bf96cL, "expression"), quotedNode_2);
    return quotedNode_1;
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept IntentionDeclaration$q4 = MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x115b81b652bL, "jetbrains.mps.lang.intentions.structure.IntentionDeclaration");
    /*package*/ static final SConcept VariableReference$TC = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference");
    /*package*/ static final SConcept ConceptFunctionParameter_node$Gy = MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x115b83c562eL, "jetbrains.mps.lang.intentions.structure.ConceptFunctionParameter_node");
    /*package*/ static final SConcept ConceptFunctionParameter_childNode$qh = MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x323731f511d1c750L, "jetbrains.mps.lang.intentions.structure.ConceptFunctionParameter_childNode");
    /*package*/ static final SConcept ConceptFunctionParameter_editorContext$eI = MetaAdapterFactory.getConcept(0x13744753c81f424aL, 0x9c1bcf8943bf4e86L, 0x11601f73f7aL, "jetbrains.mps.lang.sharedConcepts.structure.ConceptFunctionParameter_editorContext");
    /*package*/ static final SConcept ChildFilterFunction$q_ = MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x323731f511d1c1bbL, "jetbrains.mps.lang.intentions.structure.ChildFilterFunction");
    /*package*/ static final SConcept Intention$zo = MetaAdapterFactory.getConcept(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x71ffad1474b12a0bL, "jetbrains.mps.lang.intentions.structure.Intention");
    /*package*/ static final SConcept MethodInstance$jE = MetaAdapterFactory.getConcept(0xc7d5b9dda05f4be2L, 0xbc73f2e16994cc67L, 0x340eb2bd2e03d154L, "jetbrains.mps.baseLanguage.lightweightdsl.structure.MethodInstance");
  }

  private static final class LINKS {
    /*package*/ static final SContainmentLink methodDeclaration$ydlK = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x118c255bfb5L, "methodDeclaration");
    /*package*/ static final SContainmentLink fieldDeclaration$sOzg = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x4ffeb1df376f7495L, "fieldDeclaration");
    /*package*/ static final SContainmentLink body$5xQk = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1ffL, "body");
    /*package*/ static final SContainmentLink statement$53DE = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b200L, 0xf8cc6bf961L, "statement");
    /*package*/ static final SReferenceLink variableDeclaration$N1XG = MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration");
    /*package*/ static final SContainmentLink parameter$5xBj = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1feL, "parameter");
    /*package*/ static final SContainmentLink executeFunction$zyVM = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3e6813L, "executeFunction");
    /*package*/ static final SContainmentLink body$e68K = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x108bbca0f48L, 0x108bbd29b4aL, "body");
    /*package*/ static final SContainmentLink descriptionFunction$xRc1 = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3cd0a9L, "descriptionFunction");
    /*package*/ static final SContainmentLink isApplicableFunction$xRE3 = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3cd0abL, "isApplicableFunction");
    /*package*/ static final SContainmentLink childFilterFunction$xRr2 = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3cd0aaL, "childFilterFunction");
    /*package*/ static final SReferenceLink forConcept$Mnu4 = MetaAdapterFactory.getReferenceLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x71ffad1474b12a0bL, 0x10d005a50b96761L, "forConcept");
    /*package*/ static final SReferenceLink forConcept$zyGL = MetaAdapterFactory.getReferenceLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3e6812L, "forConcept");
    /*package*/ static final SContainmentLink priority$HQFL = MetaAdapterFactory.getContainmentLink(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x71ffad1474b12a0bL, 0x59427edd75744671L, "priority");
  }

  private static final class PROPS {
    /*package*/ static final SProperty isErrorIntention$Mcvw = MetaAdapterFactory.getProperty(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3cc679L, "isErrorIntention");
    /*package*/ static final SProperty isAvailableInChildNodes$McIx = MetaAdapterFactory.getProperty(0xd7a92d38f7db40d0L, 0x8431763b0c3c9f20L, 0x2303633a9c3cc675L, 0x2303633a9c3cc67aL, "isAvailableInChildNodes");
    /*package*/ static final SProperty name$MnvL = MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name");
    /*package*/ static final SProperty virtualPackage$EkXl = MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, 0x115eca8579fL, "virtualPackage");
  }
}
