package jetbrains.mps.lang.migration.runtime.base;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import jetbrains.mps.logging.Logger;
import org.jetbrains.mps.openapi.language.SLanguage;
import jetbrains.mps.smodel.adapter.ids.MetaIdHelper;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.smodel.adapter.ids.SLanguageId;
import jetbrains.mps.smodel.language.LanguageRegistry;
import jetbrains.mps.project.Project;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.smodel.language.LanguageRuntime;

@GeneratedClass(node = "528ff3b9-5fc4-40dd-931f-c6ce3650640e/r:f69c3fa1-0e30-4980-84e2-190ae44e4c3d(jetbrains.mps.lang.migration.runtime/jetbrains.mps.lang.migration.runtime.base)/3309033097910132680", model = "528ff3b9-5fc4-40dd-931f-c6ce3650640e/r:f69c3fa1-0e30-4980-84e2-190ae44e4c3d(jetbrains.mps.lang.migration.runtime/jetbrains.mps.lang.migration.runtime.base)")
public class MigrationScriptReference implements BaseScriptReference<MigrationScript> {
  private static final Logger LOG = Logger.getLogger(MigrationScriptReference.class);
  private final SLanguage language;
  private final int fromVersion;
  public MigrationScriptReference(SLanguage language, int fromVersion) {
    this.language = language;
    this.fromVersion = fromVersion;
  }
  public SLanguage getLanguage() {
    return language;
  }
  public int getFromVersion() {
    return fromVersion;
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || this.getClass() != o.getClass()) {
      return false;
    }
    MigrationScriptReference that = (MigrationScriptReference) o;
    if (!(language.equals(that.language))) {
      return false;
    }
    if (fromVersion != that.fromVersion) {
      return false;
    }
    return true;
  }
  @Override
  public int hashCode() {
    return language.hashCode() + 31 * fromVersion;
  }
  @Override
  public String toString() {
    return "Migration[" + language.getQualifiedName() + ";" + fromVersion + "]";
  }
  public String serialize() {
    return MetaIdHelper.getLanguage(language).serialize() + "(" + language.getQualifiedName() + ")" + "/" + fromVersion;
  }
  public static MigrationScriptReference deserialize(String s) {
    int version = Integer.parseInt(s.substring(s.indexOf('/') + 1));
    int ix = s.indexOf('(');
    SLanguage language = MetaAdapterFactory.getLanguage(SLanguageId.deserialize(s.substring(0, ix)), s.substring(ix + 1, s.indexOf(')', ix)));
    return new MigrationScriptReference(language, version);
  }

  /**
   * 
   * @deprecated script reference has to stay reference only, and resolution logic shall be kept outside to avoid unnecessary re-resolve of the script instance. See {@link jetbrains.mps.lang.migration.runtime.base.MigrationScriptReference#resolve(LanguageRegistry, MigrationScriptReference) }
   */
  @Override
  @Deprecated(forRemoval = true, since = "2023.1")
  public MigrationScript resolve(Project p, boolean silent) {
    return resolve(p.getComponent(LanguageRegistry.class), this);
  }

  @Nullable
  public static MigrationScript resolve(LanguageRegistry languageRegistry, MigrationScriptReference scriptRef) {
    return resolve(languageRegistry.getLanguage(scriptRef.getLanguage()), scriptRef.getFromVersion());
  }

  @Nullable
  public static MigrationScript resolve(final LanguageRuntime languageRuntime, final int fromVersion) {
    MigrationAspectDescriptor md = languageRuntime.getAspect(MigrationAspectDescriptor.class);
    if (md == null) {
      if (LOG.isWarningLevel()) {
        LOG.warning(String.format("Could not load migration descriptor for language %s.", languageRuntime.getNamespace()));
      }
      return null;
    }
    MigrationScript script = md.getScript(fromVersion);
    if (script == null) {
      if (LOG.isWarningLevel()) {
        LOG.warning(String.format("Could not load migration script for language %s, version %d.", languageRuntime.getNamespace(), fromVersion));
      }
      return null;
    }
    return script;
  }
}
