package jetbrains.mps.lang.structure.scripts;

/*Generated by MPS */

import jetbrains.mps.lang.script.runtime.BaseMigrationScript;
import jetbrains.mps.lang.script.runtime.AbstractMigrationRefactoring;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.language.SProperty;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import org.jetbrains.mps.openapi.model.SReference;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;

public final class DeleteUndeclaredLinksAndProperties_MigrationScript extends BaseMigrationScript {
  public DeleteUndeclaredLinksAndProperties_MigrationScript() {
    super("Delete Undeclared Links and Properties");
    this.addRefactoring(new AbstractMigrationRefactoring() {
      @Override
      public String getName() {
        return "Undeclared property";
      }
      @Override
      public String getAdditionalInfo() {
        return "Undeclared property";
      }
      @Override
      public SAbstractConcept getApplicableConcept() {
        return CONCEPTS.BaseConcept$gP;
      }
      @Override
      public boolean isApplicableInstanceNode(SNode node) {
        for (SProperty prop : Sequence.fromIterable(node.getProperties())) {
          if (!(prop.isValid())) {
            return true;
          }
        }
        return false;
      }
      @Override
      public void doUpdateInstanceNode(SNode node) {
        for (SProperty prop : Sequence.fromIterable(node.getProperties())) {
          if (!(prop.isValid())) {
            node.setProperty(prop, null);
          }
        }
      }
      @Override
      public boolean isShowAsIntention() {
        return false;
      }
    });
    this.addRefactoring(new AbstractMigrationRefactoring() {
      @Override
      public String getName() {
        return "Child in undeclared role";
      }
      @Override
      public String getAdditionalInfo() {
        return "Child in undeclared role";
      }
      @Override
      public SAbstractConcept getApplicableConcept() {
        return CONCEPTS.BaseConcept$gP;
      }
      @Override
      public boolean isApplicableInstanceNode(SNode node) {
        return (SNodeOperations.getParent(node) != null) && !(SNodeOperations.getContainingLink(node).isValid());
      }
      @Override
      public void doUpdateInstanceNode(SNode node) {
        SNodeOperations.deleteNode(node);
      }
      @Override
      public boolean isShowAsIntention() {
        return false;
      }
    });
    this.addRefactoring(new AbstractMigrationRefactoring() {
      @Override
      public String getName() {
        return "Undeclared reference";
      }
      @Override
      public String getAdditionalInfo() {
        return "Undeclared reference";
      }
      @Override
      public SAbstractConcept getApplicableConcept() {
        return CONCEPTS.BaseConcept$gP;
      }
      @Override
      public boolean isApplicableInstanceNode(SNode node) {
        return ListSequence.fromList(SNodeOperations.getReferences(node)).any((it) -> !(SLinkOperations.getRefLink(it).isValid()));
      }
      @Override
      public void doUpdateInstanceNode(SNode node) {
        for (SReference ref : ListSequence.fromList(SNodeOperations.getReferences(node)).where((it) -> !(SLinkOperations.getRefLink(it).isValid())).toGenericArray(SReference.class)) {
          node.dropReference(ref.getLink());
        }
      }
      @Override
      public boolean isShowAsIntention() {
        return false;
      }
    });
  }

  @Nullable
  @Override
  public SNodeReference getScriptNode() {
    return PersistenceFacade.getInstance().createNodeReference("r:00000000-0000-4000-0000-011c89590291(jetbrains.mps.lang.structure.scripts)/6066872190921237633");
  }

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