package jetbrains.mps.lang.smodel.migration;

/*Generated by MPS */

import jetbrains.mps.lang.migration.runtime.base.MigrationScriptBase;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.module.SearchScope;
import jetbrains.mps.lang.smodel.query.runtime.CommandUtil;
import jetbrains.mps.project.EditableFilteringScope;
import jetbrains.mps.lang.smodel.query.runtime.QueryExecutionContext;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.typechecking.TypecheckingFacade;
import jetbrains.mps.lang.migration.runtime.base.MigrationScriptReference;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import org.jetbrains.mps.openapi.language.SConcept;

public class ExplicitNodePresentation extends MigrationScriptBase {
  private final String description = "Replace implicit node.toString() with explicit smodel operation";
  public String getCaption() {
    return description;
  }
  @Override
  public boolean isRerunnable() {
    return true;
  }
  public SNode execute(final SModule m) {
    doExecute(m);
    return null;
  }
  public void doExecute(final SModule m) {
    {
      SearchScope scope_skz2ag_a0e = CommandUtil.createScope(m);
      final SearchScope scope_skz2ag_a0e_0 = new EditableFilteringScope(scope_skz2ag_a0e);
      QueryExecutionContext context = () -> scope_skz2ag_a0e_0;
      for (SNode pe : CollectionSequence.fromCollection(CommandUtil.instances(CommandUtil.selectScope(null, context), CONCEPTS.PlusExpression$k0, false))) {
        // handle ""+node and node+"" cases
        if (SNodeOperations.isInstanceOf(SLinkOperations.getTarget(pe, LINKS.leftExpression$sEj), CONCEPTS.StringLiteral$xu) && SNodeOperations.isInstanceOf(TypecheckingFacade.getFromContext().getTypeOf(SLinkOperations.getTarget(pe, LINKS.rightExpression$nvX)), CONCEPTS.SNodeType$hR)) {
          SNode nodeExpr = SLinkOperations.getTarget(pe, LINKS.rightExpression$nvX);
          SNode de = SNodeOperations.replaceWithNewChild(SLinkOperations.getTarget(pe, LINKS.rightExpression$nvX), CONCEPTS.DotExpression$yW);
          SLinkOperations.setTarget(de, LINKS.operand$w6IR, nodeExpr);
          SLinkOperations.setNewChild(de, LINKS.operation$gs9E, CONCEPTS.Node_PresentationOperation$DL);
        }
        if (SNodeOperations.isInstanceOf(SLinkOperations.getTarget(pe, LINKS.rightExpression$nvX), CONCEPTS.StringLiteral$xu) && SNodeOperations.isInstanceOf(TypecheckingFacade.getFromContext().getTypeOf(SLinkOperations.getTarget(pe, LINKS.leftExpression$sEj)), CONCEPTS.SNodeType$hR)) {
          SNode nodeExpr = SLinkOperations.getTarget(pe, LINKS.leftExpression$sEj);
          SNode de = SNodeOperations.replaceWithNewChild(SLinkOperations.getTarget(pe, LINKS.leftExpression$sEj), CONCEPTS.DotExpression$yW);
          SLinkOperations.setTarget(de, LINKS.operand$w6IR, nodeExpr);
          SLinkOperations.setNewChild(de, LINKS.operation$gs9E, CONCEPTS.Node_PresentationOperation$DL);
        }
      }
    }
  }
  public MigrationScriptReference getReference() {
    return new MigrationScriptReference(MetaAdapterFactory.getLanguage(0x7866978ea0f04cc7L, 0x81bc4d213d9375e1L, "jetbrains.mps.lang.smodel"), 18);
  }

  private static final class LINKS {
    /*package*/ static final SContainmentLink rightExpression$nvX = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11bL, "rightExpression");
    /*package*/ static final SContainmentLink leftExpression$sEj = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbdeb6fecfL, 0xfbdeb7a11cL, "leftExpression");
    /*package*/ static final SContainmentLink operand$w6IR = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46a4416L, "operand");
    /*package*/ static final SContainmentLink operation$gs9E = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, 0x116b46b36c4L, "operation");
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept SNodeType$hR = MetaAdapterFactory.getConcept(0x7866978ea0f04cc7L, 0x81bc4d213d9375e1L, 0x108f968b3caL, "jetbrains.mps.lang.smodel.structure.SNodeType");
    /*package*/ static final SConcept StringLiteral$xu = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf93d565d10L, "jetbrains.mps.baseLanguage.structure.StringLiteral");
    /*package*/ static final SConcept DotExpression$yW = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x116b46a08c4L, "jetbrains.mps.baseLanguage.structure.DotExpression");
    /*package*/ static final SConcept Node_PresentationOperation$DL = MetaAdapterFactory.getConcept(0x7866978ea0f04cc7L, 0x81bc4d213d9375e1L, 0x739a0840dde65ea1L, "jetbrains.mps.lang.smodel.structure.Node_PresentationOperation");
    /*package*/ static final SConcept PlusExpression$k0 = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc67c7fbL, "jetbrains.mps.baseLanguage.structure.PlusExpression");
  }
}
