// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8;

import com.android.tools.r8.utils.VersionProperties;

/** Version of the D8/R8 library. */
public final class Version {

  private static final String MAIN_LABEL = "8.2.0-dev";

  // This field is accessed from release scripts using simple pattern matching.
  // Therefore, changing this field could break our release scripts.
  public static final String LABEL = "8.2.0-dev";

  private Version() {
  }

  /** Returns current R8 version (with additional info) as a string. */
  public static String getVersionString() {
    return LABEL + " (" + VersionProperties.INSTANCE.getDescription() + ")";
  }

  /**
   * Returns the major version number of the compiler.
   *
   * @return Major version or -1 for an unreleased build.
   */
  public static int getMajorVersion() {
    return getMajorVersion(LABEL);
  }

  static int getMajorVersion(String label) {
    if (label.equals(MAIN_LABEL)) {
      return -1;
    }
    int start = 0;
    int end = label.indexOf('.');
    return Integer.parseInt(label.substring(start, end));
  }

  /**
   * Returns the minor version number of the compiler.
   *
   * @return Minor version or -1 for an unreleased build.
   */
  public static int getMinorVersion() {
    return getMinorVersion(LABEL);
  }

  static int getMinorVersion(String label) {
    if (label.equals(MAIN_LABEL)) {
      return -1;
    }
    int start = label.indexOf('.') + 1;
    int end = label.indexOf('.', start);
    return Integer.parseInt(label.substring(start, end));
  }

  /**
   * Returns the patch version number of the compiler.
   *
   * @return Patch version or -1 for an unreleased build.
   */
  public static int getPatchVersion() {
    return getPatchVersion(LABEL);
  }

  static int getPatchVersion(String label) {
    if (label.equals(MAIN_LABEL)) {
      return -1;
    }
    int skip = label.indexOf('.') + 1;
    int start = label.indexOf('.', skip) + 1;
    int end = label.indexOf('-', start);
    return Integer.parseInt(label.substring(start, end != -1 ? end : label.length()));
  }

  /**
   * Returns the pre-release version information of the compiler.
   *
   * @return Pre-release information if present, the empty string if absent, and null for an
   *     unreleased build.
   */
  public static String getPreReleaseString() {
    return getPreReleaseString(LABEL);
  }

  static String getPreReleaseString(String label) {
    if (label.equals(MAIN_LABEL)) {
      return null;
    }
    int start = label.indexOf('-') + 1;
    if (start > 0) {
      return label.substring(start);
    }
    return "";
  }

  /**
   * Is this a development version of the D8/R8 library.
   *
   * @return True if the build is not a release or if it is a development release.
   */
  public static boolean isDevelopmentVersion() {
    return isDevelopmentVersion(LABEL, VersionProperties.INSTANCE.isEngineering());
  }

  static boolean isDevelopmentVersion(String label, boolean isEngineering) {
    return label.equals(MAIN_LABEL) || label.endsWith("-dev") || isEngineering;
  }

  public static boolean isMainVersion() {
    return LABEL.equals(MAIN_LABEL);
  }
}
