package jetbrains.mps.baseLanguage.util.plugin.refactorings;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.module.SearchScope;
import jetbrains.mps.ide.findusages.model.SearchResults;
import jetbrains.mps.ide.findusages.view.FindUtils;
import jetbrains.mps.progress.EmptyProgressMonitor;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.builder.SNodeBuilder;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.model.SNodeAccessUtil;
import org.jetbrains.mps.openapi.language.SReferenceLink;
import org.jetbrains.mps.openapi.language.SContainmentLink;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SInterfaceConcept;

public class MoveStaticMethodRefactoring extends BasicMoveRefactoring {
  public MoveStaticMethodRefactoring(SNode moving, SNode destination) {
    super(moving, destination);
  }

  public MoveStaticMethodRefactoring(SRepository repository, final SearchScope scope, SNode moving, SNode destination) {
    super(moving, destination);
    repository.getModelAccess().runReadAction(new Runnable() {
      public void run() {
        SearchResults<SNode> results = FindUtils.getSearchResults(new EmptyProgressMonitor(), myMoving, scope, "jetbrains.mps.baseLanguage.findUsages.ExactMethodUsages_Finder");
        setUsages(results);
      }
    });
  }

  public static void replaceFields(SNode movingMethod, SNode originalClass) {
    for (SNode field : ListSequence.fromList(SNodeOperations.getNodeDescendants(movingMethod, CONCEPTS.VariableReference$TC, false, new SAbstractConcept[]{})).where(new _FunctionTypes._return_P1_E0<Boolean, SNode>() {
      public Boolean invoke(SNode it) {
        return SConceptOperations.isExactly(SNodeOperations.asSConcept(SNodeOperations.getConcept(it)), CONCEPTS.VariableReference$TC) && SNodeOperations.isInstanceOf(SLinkOperations.getTarget(SNodeOperations.cast(it, CONCEPTS.VariableReference$TC), LINKS.variableDeclaration$N1XG), CONCEPTS.StaticFieldDeclaration$jR);
      }
    })) {
      SNodeOperations.replaceWithAnother(field, _quotation_createNode_f5lqsg_a0a0a0a4(originalClass, SLinkOperations.getTarget(field, LINKS.variableDeclaration$N1XG)));
    }
  }

  public static void replaceMethods(SNode movingMethod, SNode originalClass) {
    for (SNode call : ListSequence.fromList(ListSequence.fromList(SNodeOperations.getNodeDescendants(movingMethod, CONCEPTS.LocalMethodCall$zT, false, new SAbstractConcept[]{})).where(new _FunctionTypes._return_P1_E0<Boolean, SNode>() {
      public Boolean invoke(SNode it) {
        return SNodeOperations.isInstanceOf(SLinkOperations.getTarget(it, LINKS.baseMethodDeclaration$pyYw), CONCEPTS.StaticMethodDeclaration$FJ);
      }
    }).toList())) {
      if (SLinkOperations.getTarget(call, LINKS.baseMethodDeclaration$pyYw) != movingMethod) {
        SNode newCall = _quotation_createNode_f5lqsg_a0a0a0a0g(originalClass, SLinkOperations.getTarget(call, LINKS.baseMethodDeclaration$pyYw));
        ListSequence.fromList(SLinkOperations.getChildren(newCall, LINKS.actualArgument$pzdx)).addSequence(ListSequence.fromList(SLinkOperations.getChildren(call, LINKS.actualArgument$pzdx)));
        ListSequence.fromList(SLinkOperations.getChildren(newCall, LINKS.typeArgument$jaIN)).addSequence(ListSequence.fromList(SLinkOperations.getChildren(call, LINKS.typeArgument$jaIN)));
        SNodeOperations.replaceWithAnother(call, newCall);
      }
    }
  }

  @Override
  protected void correctMoving() {
    SNode containingClass = SNodeOperations.getNodeAncestor(myMoving, CONCEPTS.ClassConcept$bK, false, false);
    replaceFields(myMoving, containingClass);
    replaceMethods(myMoving, containingClass);
  }

  @Override
  public void replaceSingleUsage(SNode usage) {
    super.replaceSingleUsage(usage);
    if (SNodeOperations.isInstanceOf(usage, CONCEPTS.IMethodCall$M9)) {
      SNode newCall;
      if (SNodeOperations.getNodeAncestor(usage, CONCEPTS.Classifier$Ix, false, false) == this.myDestination) {
        newCall = _quotation_createNode_f5lqsg_a0a0b0b0k(this.myReplacing);
      } else {
        newCall = _quotation_createNode_f5lqsg_a0a0a1a1a01(this.myDestination, this.myReplacing);
      }
      ListSequence.fromList(SLinkOperations.getChildren(newCall, LINKS.actualArgument$pzdx)).addSequence(ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(usage, CONCEPTS.IMethodCall$M9), LINKS.actualArgument$pzdx)));
      ListSequence.fromList(SLinkOperations.getChildren(newCall, LINKS.typeArgument$jaIN)).addSequence(ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(usage, CONCEPTS.IMethodCall$M9), LINKS.typeArgument$jaIN)));
      SNodeOperations.replaceWithAnother(usage, newCall);
    }
  }
  private static SNode _quotation_createNode_f5lqsg_a0a0a0a4(Object parameter_1, Object parameter_2) {
    SNode quotedNode_3 = null;
    SNodeBuilder nb = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940c80846L, "StaticFieldReference"));
    quotedNode_3 = nb.getResult();
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940c80846L, 0x10a75869f9bL, "classifier"), (SNode) parameter_1);
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"), (SNode) parameter_2);
    return quotedNode_3;
  }
  private static SNode _quotation_createNode_f5lqsg_a0a0a0a0g(Object parameter_1, Object parameter_2) {
    SNode quotedNode_3 = null;
    SNodeBuilder nb = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xfbbebabf09L, "StaticMethodCall"));
    quotedNode_3 = nb.getResult();
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"), (SNode) parameter_2);
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, 0x10a7588b546L, "classConcept"), (SNode) parameter_1);
    return quotedNode_3;
  }
  private static SNode _quotation_createNode_f5lqsg_a0a0b0b0k(Object parameter_1) {
    SNode quotedNode_2 = null;
    SNodeBuilder nb = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0x6c6b6a1e379f9404L, "LocalMethodCall"));
    quotedNode_2 = nb.getResult();
    SNodeAccessUtil.setReferenceTarget(quotedNode_2, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"), (SNode) parameter_1);
    return quotedNode_2;
  }
  private static SNode _quotation_createNode_f5lqsg_a0a0a1a1a01(Object parameter_1, Object parameter_2) {
    SNode quotedNode_3 = null;
    SNodeBuilder nb = new SNodeBuilder(null, null).init(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xfbbebabf09L, "StaticMethodCall"));
    quotedNode_3 = nb.getResult();
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"), (SNode) parameter_2);
    SNodeAccessUtil.setReferenceTarget(quotedNode_3, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf09L, 0x10a7588b546L, "classConcept"), (SNode) parameter_1);
    return quotedNode_3;
  }

  private static final class LINKS {
    /*package*/ static final SReferenceLink variableDeclaration$N1XG = MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration");
    /*package*/ static final SReferenceLink baseMethodDeclaration$pyYw = MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration");
    /*package*/ static final SContainmentLink actualArgument$pzdx = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301aeL, "actualArgument");
    /*package*/ static final SContainmentLink typeArgument$jaIN = MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0x4500f31eb02a7788L, "typeArgument");
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept VariableReference$TC = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference");
    /*package*/ static final SConcept StaticFieldDeclaration$jR = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf93c84351fL, "jetbrains.mps.baseLanguage.structure.StaticFieldDeclaration");
    /*package*/ static final SConcept LocalMethodCall$zT = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x6c6b6a1e379f9404L, "jetbrains.mps.baseLanguage.structure.LocalMethodCall");
    /*package*/ static final SConcept StaticMethodDeclaration$FJ = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xfbbebabf0aL, "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration");
    /*package*/ static final SConcept ClassConcept$bK = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c108ca66L, "jetbrains.mps.baseLanguage.structure.ClassConcept");
    /*package*/ static final SConcept Classifier$Ix = MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier");
    /*package*/ static final SInterfaceConcept IMethodCall$M9 = MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall");
  }
}
