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

  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 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 : "");
  }
}
