from typing import Tuple
import re


def check_tvm_version(curr: str, min_req: str) -> bool:
    """Check if the current TVM version satisfies the minimum requirement.

    Parameters
    ----------
    curr: str
        The current version.

    min_req: str
        The minimum requirement version.

    Returns
    -------
    check: bool
        Return true if the current version satisfies the minimum requirement.
    """

    def parse_version(ver_str: str) -> Tuple[Tuple[int, int, int], bool]:
        """Parse TVM version to a tuple-3.

        Parameters
        ----------
        ver_str: str
            The TVM version string.

        Returns
        -------
        ver: Tuple[Tuple[int, int, int], bool]
            (3-way version number, is a release version)
        """

        # The release version such as 0.8.0.
        tokens = re.search(r"(\d|)\.(\d+)\.(\d+)", ver_str)
        if tokens is not None:
            return ((int(tokens.group(1)), int(tokens.group(2)), int(tokens.group(3))), True)

        # The dev version such as 0.8.dev0 or 0.8.dev94+g0d07a329e.
        tokens = re.search(r"(\d|)\.(\d+)\.dev(\d+)\+*.*", ver_str)
        if tokens is not None:
            return ((int(tokens.group(1)), int(tokens.group(2)), int(tokens.group(3))), False)

        raise RuntimeError("Unrecognized TVM version: %s" % ver_str)

    curr_ver, curr_rel = parse_version(curr)
    req_ver, req_rel = parse_version(min_req)

    # Major version.
    if curr_ver[0] < req_ver[0]:
        return False
    if curr_ver[0] > req_ver[0]:
        return True

    # Miner version.
    if curr_ver[1] < req_ver[1]:
        return False
    if curr_ver[1] > req_ver[1]:
        return True

    if curr_rel and not req_rel:
        # Current version is "release" but the target version is "dev".
        return True
    if not curr_rel and req_rel:
        # Current version is "dev" but the target version is "release".
        return False

    # Both are "dev" versions.
    return curr_ver[2] >= req_ver[2]