// 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 {

  // 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 = "3.0.41-sc04";

  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")) {
      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")) {
      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")) {
      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")) {
      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.endsWith("-dev") || isEngineering;
  }
}
