package jetbrains.mps.lang.typesystem.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.lang.structure.migration.EnumUsagesMigration;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import jetbrains.mps.lang.pattern.migration.PropertyPatternVariableMigration;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.lang.migration.runtime.base.Problem;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.migration.runtime.base.UsageOfMigrateNodeNotMigratedProblem;
import jetbrains.mps.lang.migration.runtime.base.MigrationScriptReference;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SReferenceLink;
import org.jetbrains.mps.openapi.language.SConcept;

public class MigrateEnumPropertyUsagesAndPropertyPatternVaraibles extends MigrationScriptBase {
  private final String description = "Migrate enumeration property usages and property pattern variables (typesystems)";
  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_qggrhk_a0e = CommandUtil.createScope(m);
      final SearchScope scope_qggrhk_a0e_0 = new EditableFilteringScope(scope_qggrhk_a0e);
      QueryExecutionContext context = () -> scope_qggrhk_a0e_0;
      EnumUsagesMigration migration = new EnumUsagesMigration();
      for (SNode propMessageTarget : CollectionSequence.fromCollection(CommandUtil.instances(CommandUtil.selectScope(null, context), CONCEPTS.PropertyMessageTarget$3N, false))) {
        migration.migratePropertyReference(propMessageTarget, LINKS.propertyDeclaration$24Tq);
      }
      new PropertyPatternVariableMigration<SNode>() {
        @Override
        protected Iterable<SNode> getUsagesToMigrate() {
          return CommandUtil.instances(CommandUtil.selectScope(null, context), CONCEPTS.PropertyPatternVariableReference$UR, false);
        }
        @Override
        protected SNode getDeclaration(SNode usage) {
          return SLinkOperations.getTarget(usage, LINKS.patternVarDecl$9tBb);
        }
        @Override
        protected void migrateRawValue(SNode usage, SNode datatype) {
          downgradeRawValueType(usage, datatype);
        }
        @Override
        protected void migrateEnumValue(SNode usage, SNode enumeration) {
          downgradeEnumType(usage, enumeration);
        }
      }.migrate();
    }
  }
  @Override
  public Iterable<Problem> check(SModule m) {
    {
      SearchScope scope_qggrhk_a0f = CommandUtil.createScope(m);
      final SearchScope scope_qggrhk_a0f_0 = new EditableFilteringScope(scope_qggrhk_a0f);
      QueryExecutionContext context = () -> scope_qggrhk_a0f_0;
      List<Problem> problems = ListSequence.fromList(new ArrayList<Problem>());
      ListSequence.fromList(problems).addSequence(CollectionSequence.fromCollection(CommandUtil.instances(CommandUtil.selectScope(null, context), CONCEPTS.PropertyMessageTarget$3N, false)).where((it) -> SNodeOperations.isInstanceOf(SNodeOperations.getParent(SLinkOperations.getTarget(it, LINKS.propertyDeclaration$24Tq)), CONCEPTS.EnumPropertyMigrationInfo$O3)).select((it) -> new UsageOfMigrateNodeNotMigratedProblem(it, SLinkOperations.getTarget(it, LINKS.propertyDeclaration$24Tq))));
      return problems;
    }
  }
  public Iterable<MigrationScriptReference> executeAfter() {
    return ListSequence.fromListAndArray(new ArrayList<MigrationScriptReference>(), new MigrationScriptReference(MetaAdapterFactory.getLanguage(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, "jetbrains.mps.lang.structure"), 8));
  }
  public MigrationScriptReference getReference() {
    return new MigrationScriptReference(MetaAdapterFactory.getLanguage(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, "jetbrains.mps.lang.typesystem"), 1);
  }

  private static final class LINKS {
    /*package*/ static final SReferenceLink propertyDeclaration$24Tq = MetaAdapterFactory.getReferenceLink(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x11db4a6a000L, 0x11db4a6fbeeL, "propertyDeclaration");
    /*package*/ static final SReferenceLink patternVarDecl$9tBb = MetaAdapterFactory.getReferenceLink(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x11192d97ff9L, 0x11192d9d83cL, "patternVarDecl");
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept PropertyMessageTarget$3N = MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x11db4a6a000L, "jetbrains.mps.lang.typesystem.structure.PropertyMessageTarget");
    /*package*/ static final SConcept PropertyPatternVariableReference$UR = MetaAdapterFactory.getConcept(0x7a5dda6291404668L, 0xab76d5ed1746f2b2L, 0x11192d97ff9L, "jetbrains.mps.lang.typesystem.structure.PropertyPatternVariableReference");
    /*package*/ static final SConcept EnumPropertyMigrationInfo$O3 = MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0x5a14f1035942a5abL, "jetbrains.mps.lang.structure.structure.EnumPropertyMigrationInfo");
  }
}
