/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.util;

import java.text.ParseException;
import java.util.Locale;

/**
 * Use by certain classes to match version compatibility across releases of Lucene.
 *
 * <p><b>WARNING</b>: When changing the version parameter that you supply to components in Lucene,
 * do not simply change the version at search-time, but instead also adjust your indexing code to
 * match, and re-index.
 */
public final class Version {

  /**
   * Match settings and bugs in Lucene's 8.0.0 release.
   *
   * @deprecated (9.0.0) Use latest
   */
  @Deprecated public static final Version LUCENE_8_0_0 = new Version(8, 0, 0);

  /**
   * Match settings and bugs in Lucene's 8.1.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_1_0 = new Version(8, 1, 0);

  /**
   * Match settings and bugs in Lucene's 8.1.1 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_1_1 = new Version(8, 1, 1);

  /**
   * Match settings and bugs in Lucene's 8.2.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_2_0 = new Version(8, 2, 0);

  /**
   * Match settings and bugs in Lucene's 8.3.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_3_0 = new Version(8, 3, 0);

  /**
   * Match settings and bugs in Lucene's 8.3.1 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_3_1 = new Version(8, 3, 1);

  /**
   * Match settings and bugs in Lucene's 8.4.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_4_0 = new Version(8, 4, 0);

  /**
   * Match settings and bugs in Lucene's 8.4.1 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_4_1 = new Version(8, 4, 1);

  /**
   * Match settings and bugs in Lucene's 8.5.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_5_0 = new Version(8, 5, 0);

  /**
   * Match settings and bugs in Lucene's 8.5.1 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_5_1 = new Version(8, 5, 1);

  /**
   * Match settings and bugs in Lucene's 8.5.2 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_5_2 = new Version(8, 5, 2);

  /**
   * Match settings and bugs in Lucene's 8.6.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_6_0 = new Version(8, 6, 0);

  /**
   * Match settings and bugs in Lucene's 8.6.1 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_6_1 = new Version(8, 6, 1);

  /**
   * Match settings and bugs in Lucene's 8.6.2 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_6_2 = new Version(8, 6, 2);

  /**
   * Match settings and bugs in Lucene's 8.6.3 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_6_3 = new Version(8, 6, 3);

  /**
   * Match settings and bugs in Lucene's 8.7.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_7_0 = new Version(8, 7, 0);

  /**
   * Match settings and bugs in Lucene's 8.8.0 release.
   *
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_8_0 = new Version(8, 8, 0);

  /**
   * Match settings and bugs in Lucene's 8.8.1 release.
   * @deprecated Use latest
   */
  @Deprecated public static final Version LUCENE_8_8_1 = new Version(8, 8, 1);

  /**
   * Match settings and bugs in Lucene's 9.0.0 release.
   *
   * <p>Use this to get the latest &amp; greatest settings, bug fixes, etc, for Lucene.
   */
  public static final Version LUCENE_9_0_0 = new Version(9, 0, 0);

  // To add a new version:
  //  * Only add above this comment
  //  * If the new version is the newest, change LATEST below and deprecate the previous LATEST

  /**
   * <b>WARNING</b>: if you use this setting, and then upgrade to a newer release of Lucene, sizable
   * changes may happen. If backwards compatibility is important then you should instead explicitly
   * specify an actual version.
   *
   * <p>If you use this constant then you may need to <b>re-index all of your documents</b> when
   * upgrading Lucene, as the way text is indexed may have changed. Additionally, you may need to
   * <b>re-test your entire application</b> to ensure it behaves as expected, as some defaults may
   * have changed and may break functionality in your application.
   */
  public static final Version LATEST = LUCENE_9_0_0;

  /**
   * Constant for backwards compatibility.
   *
   * @deprecated Use {@link #LATEST}
   */
  @Deprecated public static final Version LUCENE_CURRENT = LATEST;

  /**
   * Constant for the minimal supported major version of an index. This version is defined by the
   * version that initially created the index.
   */
  public static final int MIN_SUPPORTED_MAJOR = Version.LATEST.major - 1;

  /**
   * Parse a version number of the form {@code "major.minor.bugfix.prerelease"}.
   *
   * <p>Part {@code ".bugfix"} and part {@code ".prerelease"} are optional. Note that this is
   * forwards compatible: the parsed version does not have to exist as a constant.
   *
   * @lucene.internal
   */
  public static Version parse(String version) throws ParseException {

    StrictStringTokenizer tokens = new StrictStringTokenizer(version, '.');
    if (tokens.hasMoreTokens() == false) {
      throw new ParseException(
          "Version is not in form major.minor.bugfix(.prerelease) (got: " + version + ")", 0);
    }

    int major;
    String token = tokens.nextToken();
    try {
      major = Integer.parseInt(token);
    } catch (NumberFormatException nfe) {
      ParseException p =
          new ParseException(
              "Failed to parse major version from \"" + token + "\" (got: " + version + ")", 0);
      p.initCause(nfe);
      throw p;
    }

    if (tokens.hasMoreTokens() == false) {
      throw new ParseException(
          "Version is not in form major.minor.bugfix(.prerelease) (got: " + version + ")", 0);
    }

    int minor;
    token = tokens.nextToken();
    try {
      minor = Integer.parseInt(token);
    } catch (NumberFormatException nfe) {
      ParseException p =
          new ParseException(
              "Failed to parse minor version from \"" + token + "\" (got: " + version + ")", 0);
      p.initCause(nfe);
      throw p;
    }

    int bugfix = 0;
    int prerelease = 0;
    if (tokens.hasMoreTokens()) {

      token = tokens.nextToken();
      try {
        bugfix = Integer.parseInt(token);
      } catch (NumberFormatException nfe) {
        ParseException p =
            new ParseException(
                "Failed to parse bugfix version from \"" + token + "\" (got: " + version + ")", 0);
        p.initCause(nfe);
        throw p;
      }

      if (tokens.hasMoreTokens()) {
        token = tokens.nextToken();
        try {
          prerelease = Integer.parseInt(token);
        } catch (NumberFormatException nfe) {
          ParseException p =
              new ParseException(
                  "Failed to parse prerelease version from \""
                      + token
                      + "\" (got: "
                      + version
                      + ")",
                  0);
          p.initCause(nfe);
          throw p;
        }
        if (prerelease == 0) {
          throw new ParseException(
              "Invalid value "
                  + prerelease
                  + " for prerelease; should be 1 or 2 (got: "
                  + version
                  + ")",
              0);
        }

        if (tokens.hasMoreTokens()) {
          // Too many tokens!
          throw new ParseException(
              "Version is not in form major.minor.bugfix(.prerelease) (got: " + version + ")", 0);
        }
      }
    }

    try {
      return new Version(major, minor, bugfix, prerelease);
    } catch (IllegalArgumentException iae) {
      ParseException pe =
          new ParseException(
              "failed to parse version string \"" + version + "\": " + iae.getMessage(), 0);
      pe.initCause(iae);
      throw pe;
    }
  }

  /**
   * Parse the given version number as a constant or dot based version.
   *
   * <p>This method allows to use {@code "LUCENE_X_Y"} constant names, or version numbers in the
   * format {@code "x.y.z"}.
   *
   * @lucene.internal
   */
  public static Version parseLeniently(String version) throws ParseException {
    String versionOrig = version;
    version = version.toUpperCase(Locale.ROOT);
    switch (version) {
      case "LATEST":
      case "LUCENE_CURRENT":
        return LATEST;
      default:
        version =
            version
                .replaceFirst("^LUCENE_(\\d+)_(\\d+)_(\\d+)$", "$1.$2.$3")
                .replaceFirst("^LUCENE_(\\d+)_(\\d+)$", "$1.$2.0")
                .replaceFirst("^LUCENE_(\\d)(\\d)$", "$1.$2.0");
        try {
          return parse(version);
        } catch (ParseException pe) {
          ParseException pe2 =
              new ParseException(
                  "failed to parse lenient version string \""
                      + versionOrig
                      + "\": "
                      + pe.getMessage(),
                  0);
          pe2.initCause(pe);
          throw pe2;
        }
    }
  }

  /**
   * Returns a new version based on raw numbers
   *
   * @lucene.internal
   */
  public static Version fromBits(int major, int minor, int bugfix) {
    return new Version(major, minor, bugfix);
  }

  /** Major version, the difference between stable and trunk */
  public final int major;
  /** Minor version, incremented within the stable branch */
  public final int minor;
  /** Bugfix number, incremented on release branches */
  public final int bugfix;
  /** Prerelease version, currently 0 (alpha), 1 (beta), or 2 (final) */
  public final int prerelease;

  // stores the version pieces, with most significant pieces in high bits
  // ie:  | 1 byte | 1 byte | 1 byte |   2 bits   |
  //         major   minor    bugfix   prerelease
  private final int encodedValue;

  private Version(int major, int minor, int bugfix) {
    this(major, minor, bugfix, 0);
  }

  private Version(int major, int minor, int bugfix, int prerelease) {
    this.major = major;
    this.minor = minor;
    this.bugfix = bugfix;
    this.prerelease = prerelease;
    // NOTE: do not enforce major version so we remain future proof, except to
    // make sure it fits in the 8 bits we encode it into:
    if (major > 255 || major < 0) {
      throw new IllegalArgumentException("Illegal major version: " + major);
    }
    if (minor > 255 || minor < 0) {
      throw new IllegalArgumentException("Illegal minor version: " + minor);
    }
    if (bugfix > 255 || bugfix < 0) {
      throw new IllegalArgumentException("Illegal bugfix version: " + bugfix);
    }
    if (prerelease > 2 || prerelease < 0) {
      throw new IllegalArgumentException("Illegal prerelease version: " + prerelease);
    }
    if (prerelease != 0 && (minor != 0 || bugfix != 0)) {
      throw new IllegalArgumentException(
          "Prerelease version only supported with major release (got prerelease: "
              + prerelease
              + ", minor: "
              + minor
              + ", bugfix: "
              + bugfix
              + ")");
    }

    encodedValue = major << 18 | minor << 10 | bugfix << 2 | prerelease;

    assert encodedIsValid();
  }

  /** Returns true if this version is the same or after the version from the argument. */
  public boolean onOrAfter(Version other) {
    return encodedValue >= other.encodedValue;
  }

  @Override
  public String toString() {
    if (prerelease == 0) {
      return "" + major + "." + minor + "." + bugfix;
    }
    return "" + major + "." + minor + "." + bugfix + "." + prerelease;
  }

  @Override
  public boolean equals(Object o) {
    return o != null && o instanceof Version && ((Version) o).encodedValue == encodedValue;
  }

  // Used only by assert:
  private boolean encodedIsValid() {
    assert major == ((encodedValue >>> 18) & 0xFF);
    assert minor == ((encodedValue >>> 10) & 0xFF);
    assert bugfix == ((encodedValue >>> 2) & 0xFF);
    assert prerelease == (encodedValue & 0x03);
    return true;
  }

  @Override
  public int hashCode() {
    return encodedValue;
  }
}
