package jetbrains.mps.editor.runtime.impl.cellActions;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodIdV2;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.smodel.action.NodeFactoryManager;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import org.jetbrains.mps.openapi.language.SConcept;

@GeneratedClass(node = "r:b9f36c08-4a75-4513-9277-a390d3426e0f(jetbrains.mps.editor.runtime.impl.cellActions)/2392036511577772646", model = "r:b9f36c08-4a75-4513-9277-a390d3426e0f(jetbrains.mps.editor.runtime.impl.cellActions)")
public class NodeCommenter {
  @NotNull
  private final SNode myNode;

  private SNode myParent;
  private SContainmentLink myContainmentLink;

  public NodeCommenter(@NotNull SNode nodeToComment) {
    myNode = nodeToComment;
  }


  /**
   * comments node specified in constructor
   * 
   * @param shouldCreateNewNodeInSingleRole true if should create new node if commented node is in singular and non optional role
   * @throws IllegalStateException if node to comment does not have parent
   * @return created comment node
   */
  @NotNull
  public SNode commentOut(final boolean shouldCreateNewNodeInSingleRole) {
    if (!(isValid())) {
      throw new IllegalStateException("Node commenter has invalid state. Node to comment has no parent. Node: " + ((String) BHReflection.invoke0(myNode, CONCEPTS.BaseConcept$gP, SMethodIdV2.create("getPresentation", 1213877396640L, 0x553941aeb020c32eL))) + " Node id: " + myNode.getNodeId());
    }
    SNode comment = createNewComment();
    getParent().insertChildBefore(LINKS.smodelAttribute$KJ43, comment, myNode);
    moveNodeUnderComment(comment);
    if (shouldCreateNewNodeInSingleRole) {
      createNewNodeInSingleRole();
    }
    return comment;
  }
  /**
   * comments node specified in constructor
   * 
   * 
   * @throws IllegalStateException if node to comment does not have parent
   * @return created comment node
   */
  @NotNull
  public SNode commentOut() {
    return commentOut(true);
  }
  private void createNewNodeInSingleRole() {
    SAbstractConcept targetConcept = getContainmentLink().getTargetConcept();
    if (!(getContainmentLink().isMultiple()) && !(getContainmentLink().isOptional())) {
      getParent().addChild(getContainmentLink(), NodeFactoryManager.createNode(targetConcept, null, getParent(), SNodeOperations.getModel(getParent())));
    }
  }

  public boolean isValid() {
    if ((getParent() == null)) {
      return false;
    }
    assert getContainmentLink() != null;
    return true;
  }

  private SNode getParent() {
    if (myParent == null) {
      myParent = SNodeOperations.getParent(myNode);
    }
    return myParent;
  }
  private SContainmentLink getContainmentLink() {
    if (myContainmentLink == null) {
      myContainmentLink = myNode.getContainmentLink();
    }
    return myContainmentLink;
  }

  private SNode createNewComment() {
    SNode newComment = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x3dcc194340c24debL, "jetbrains.mps.lang.core.structure.BaseCommentAttribute"));
    BHReflection.invoke0(newComment, CONCEPTS.ChildAttribute$m8, SMethodIdV2.create("setLink", 709746936026609906L, 0x553941aeb020c32eL), getContainmentLink());
    return newComment;
  }
  private void moveNodeUnderComment(SNode comment) {
    SLinkOperations.setTarget(comment, LINKS.commentedNode$MYvG, myNode);
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept BaseConcept$gP = MetaAdapterFactory.getConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, "jetbrains.mps.lang.core.structure.BaseConcept");
    /*package*/ static final SConcept ChildAttribute$m8 = MetaAdapterFactory.getConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x9d98713f247885aL, "jetbrains.mps.lang.core.structure.ChildAttribute");
  }

  private static final class LINKS {
    /*package*/ static final SContainmentLink smodelAttribute$KJ43 = MetaAdapterFactory.getContainmentLink(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, 0x47bf8397520e5942L, "smodelAttribute");
    /*package*/ static final SContainmentLink commentedNode$MYvG = MetaAdapterFactory.getContainmentLink(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x3dcc194340c24debL, 0x2ab99f0d2248e89dL, "commentedNode");
  }
}
