# AUTOGENERATED - modify shared_anyscale_util in root directory to make changes
from typing import Tuple


def _number_value(s: str) -> int:
    try:
        return int(s)
    except ValueError:
        return 0


def _number_suffix_split(s: str) -> Tuple[str, str]:
    n = len(s)
    for i in range(n):
        if not s[n - 1 - i].isdigit():
            return s[: n - i], s[n - i :]
    return "", s  # all digits


def _number_prefix_split(s: str) -> Tuple[str, str]:
    n = len(s)
    for i in range(n):
        if not s[i].isdigit():
            return s[:i], s[i:]
    return s, ""  # all digits


def ray_semver_compare(a: str, b: str) -> int:  # noqa: PLR0911 PLR0912
    """
    A dumb implementation of semver comparison because ray versions
    don't actually follow the semver standard.


    The standard for semver versions is
    "{MAJOR}.{MINOR}.{PATCH}-{PRE_RELEASE_VERSION}," such as 2.7.0 or 2.7.0-oss
    for Ray versions. However, since we use hyphens in the codebase to split
    and extract information, our standard for Ray versions is
    "{MAJOR}.{MINOR}.{PATCH}{PRE_RELEASE_VERSION}," like 2.7.0oss
    without "-" between the patch and the pre-release version.

    Two versions are equal if they are the same string.

    Example:
        ray_semver_compare("2.7.0", "2.7.0optimized") == -1
        ray_semver_compare("2.0.1rc1", "2.0.1rc2") == -1
    """
    if a == b:
        return 0
    if a == "":
        return -1
    if b == "":
        return 1

    a_parts = a.split(".")
    b_parts = b.split(".")

    for i, a_part in enumerate(a_parts):
        if i >= len(b_parts):
            # No b has no part anymore, then a is greater.
            return 1

        b_part = b_parts[i]
        if a_part == b_part:
            continue

        if i == 0:
            # looks like ray2
            a_str, a_num_str = _number_suffix_split(a_part)
            b_str, b_num_str = _number_suffix_split(b_part)
            a_tuples0 = (a_str, _number_value(a_num_str), a_num_str, a_part)
            b_tuples0 = (b_str, _number_value(b_num_str), b_num_str, b_part)
            return 1 if a_tuples0 > b_tuples0 else -1
        a_num_str, a_str = _number_prefix_split(a_part)
        b_num_str, b_str = _number_prefix_split(b_part)
        a_tuples = (_number_value(a_num_str), a_num_str, a_str, a_part)
        b_tuples = (_number_value(b_num_str), b_num_str, b_str, b_part)
        return 1 if a_tuples > b_tuples else -1

    if len(a_parts) < len(b_parts):
        return -1
    return 1 if a > b else -1
