// Copyright (c) 2020, 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.utils;

import java.util.Objects;

public class SemanticVersion implements Comparable<SemanticVersion> {

  private static SemanticVersion MIN = SemanticVersion.create(0, 0, 0);
  private static SemanticVersion MAX =
      SemanticVersion.create(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);

  public static SemanticVersion parse(String version) {
    int majorEnd = version.indexOf('.');
    if (majorEnd <= 0) {
      throw new IllegalArgumentException("Invalid semantic version: " + version);
    }
    int minorEnd = version.indexOf('.', majorEnd + 1);
    if (minorEnd <= majorEnd + 1) {
      throw new IllegalArgumentException("Invalid semantic version: " + version);
    }
    int patchEnd = version.indexOf('-', minorEnd + 1);
    int prereleaseEnd = -1;
    if (patchEnd == -1) {
      patchEnd = version.length();
    } else {
      if (patchEnd <= minorEnd + 1) {
        throw new IllegalArgumentException("Invalid semantic version: " + version);
      }
      prereleaseEnd = version.length();
    }
    int major;
    int minor;
    int patch;
    String prerelease;
    try {
      major = Integer.parseInt(version.substring(0, majorEnd));
      minor = Integer.parseInt(version.substring(majorEnd + 1, minorEnd));
      patch = Integer.parseInt(version.substring(minorEnd + 1, patchEnd));
      prerelease = prereleaseEnd < 0 ? null : version.substring(patchEnd + 1, prereleaseEnd);
    } catch (NumberFormatException e) {
      throw new IllegalArgumentException("Invalid semantic version: " + version, e);
    }
    return create(major, minor, patch, prerelease);
  }

  private final int major;
  private final int minor;
  private final int patch;
  private final String prerelease;

  private SemanticVersion(int major, int minor, int patch, String prerelease) {
    this.major = major;
    this.minor = minor;
    this.patch = patch;
    this.prerelease = prerelease;
  }

  public static SemanticVersion create(int major, int minor, int patch) {
    return create(major, minor, patch, null);
  }

  public static SemanticVersion create(int major, int minor, int patch, String prerelease) {
    return new SemanticVersion(major, minor, patch, prerelease);
  }

  public static SemanticVersion min() {
    return MIN;
  }

  public static SemanticVersion max() {
    return MAX;
  }

  public int getMajor() {
    return major;
  }

  public int getMinor() {
    return minor;
  }

  public int getPatch() {
    return patch;
  }

  public boolean isNewerOrEqual(SemanticVersion other) {
    if (major != other.major) {
      return major > other.major;
    }
    if (minor != other.minor) {
      return minor > other.minor;
    }
    return patch >= other.patch;
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof SemanticVersion)) {
      return false;
    }
    SemanticVersion other = (SemanticVersion) obj;
    return major == other.major
        && minor == other.minor
        && patch == other.patch
        && Objects.equals(prerelease, other.prerelease);
  }

  @Override
  public int hashCode() {
    return Objects.hash(major, minor, patch, prerelease);
  }

  @Override
  public String toString() {
    return "" + major + "." + minor + "." + patch + (prerelease != null ? "-" + prerelease : "");
  }

  @Override
  public int compareTo(SemanticVersion other) {
    if (equals(other)) {
      return 0;
    }
    return isNewerOrEqual(other) ? -1 : 1;
  }
}
