// Copyright 2025 The Bazel Authors. All rights reserved.
//
// Licensed 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.

#include "src/main/cpp/sem_ver.h"

#include <cstddef>
#include <optional>
#include <string>
#include <vector>

#include "absl/strings/numbers.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "re2/re2.h"

namespace blaze {
namespace {
// Semantic version regex copied verbatim from
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
const LazyRE2 kSemverRe = {R"(^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$)"};
}  // namespace

std::optional<SemVer> SemVer::Parse(const std::string& v) {
  int major;
  int minor;
  int patch;
  std::string prerelease;
  std::string buildmetadata;
  if (RE2::FullMatch(v, *kSemverRe, &major, &minor, &patch, &prerelease,
                     &buildmetadata)) {
    return SemVer(major, minor, patch, prerelease, buildmetadata);
  }
  return std::nullopt;
}

SemVer SemVer::NextMajorVersion() const {
  return SemVer(major_ + 1, 0, 0, "", "");
}

SemVer SemVer::NextMinorVersion() const {
  return SemVer(major_, minor_ + 1, 0, "", "");
}

int SemVer::Compare(const SemVer& other) const {
  auto major_diff = major_ - other.major_;
  if (major_diff != 0) {
    return major_diff;
  }
  auto minor_diff = minor_ - other.minor_;
  if (minor_diff != 0) {
    return minor_diff;
  }
  auto patch_diff = patch_ - other.patch_;
  if (patch_diff != 0) {
    return patch_diff;
  }
  return ComparePrerelease(prerelease_, other.prerelease_);
}

// Adapted from golang's implementation.
// https://cs.opensource.google/go/x/mod/+/refs/tags/v0.30.0:semver/semver.go;l=339;bpv=1
int SemVer::ComparePrerelease(absl::string_view x,
                                         absl::string_view y) {
  if (x == y) {
    return 0;
  }
  // A larger set of pre-release fields has a higher precedence than a smaller
  // set.
  if (x.empty()) {
    return 1;
  }
  if (y.empty()) {
    return -1;
  }

  // Examine each dot-separated part.
  const std::vector<absl::string_view> xv = absl::StrSplit(x, '.');
  const std::vector<absl::string_view> yv = absl::StrSplit(y, '.');
  std::size_t i = 0;
  while (i != xv.size() && i != yv.size()) {
    auto part_x = xv[i];
    auto part_y = yv[i];
    i++;
    if (part_x != part_y) {
      int ix;
      int iy;
      bool is_numeric_x = absl::SimpleAtoi(part_x, &ix);
      bool is_numeric_y = absl::SimpleAtoi(part_y, &iy);

      if (is_numeric_x != is_numeric_y) {
        // Numeric identifiers always have lower precedence than non-numeric
        // identifiers.
        if (is_numeric_x) {
          return -1;
        }
        return 1;
      }

      if (is_numeric_x) {  // Both parts are numbers.
        if (ix < iy) {
          return -1;
        }
        return 1;
      }

      // Lexicographic ordering.
      if (part_x < part_y) {
        return -1;
      }
      return 1;
    }
  }
  // A larger set of pre-release fields has a higher precedence than a smaller
  // set.
  if (i == xv.size()) {  // We ran out of x parts.
    return -1;
  }
  return 1;
}

bool SemVer::operator==(const SemVer& other) const {
  return Compare(other) == 0;
}

bool SemVer::operator<(const SemVer& other) const { return Compare(other) < 0; }

bool SemVer::operator!=(const SemVer& other) const {
  return Compare(other) != 0;
}

bool SemVer::operator>(const SemVer& other) const { return Compare(other) > 0; }

bool SemVer::operator<=(const SemVer& other) const {
  return Compare(other) <= 0;
}

bool SemVer::operator>=(const SemVer& other) const {
  return Compare(other) >= 0;
}

}  // namespace blaze
