"""The version of this build, in one place.

Read by health, by metrics, and by the CMS — which records it against every
proposal, so "which agent produced this?" has an answer months later when the
question is being asked because something looks wrong.

pyproject.toml carries the same number because packaging tools need it there.
Two copies of a fact drift, so `test_release_version.py` fails when they
disagree rather than trusting anyone to remember. Neither file is the "real"
one; they are simply required to match.
"""

from __future__ import annotations

import re

VERSION = "0.1.0"

#: A release version: MAJOR.MINOR.PATCH, optionally with a pre-release suffix.
#:
#: Matches what the License Server's `version_compare` handles, because a
#: version this accepts and that rejects would be a release nobody can install.
VERSION_PATTERN = re.compile(r"^\d+\.\d+\.\d+(?:[-.][0-9A-Za-z.]+)?$")


def is_valid(version: str) -> bool:
    return bool(VERSION_PATTERN.match(version.strip()))


def parts(version: str) -> tuple[int, int, int]:
    """The numeric part, for comparison.

    Any pre-release suffix is dropped: 1.2.0-rc1 sorts as 1.2.0 here. That is
    deliberate for compatibility *floors* — a release candidate of 1.2.0 should
    satisfy "requires at least 1.2.0" — and it is why pre-releases belong on a
    separate channel rather than being ordered against stable ones.
    """
    if not is_valid(version):
        raise ValueError(f"Not a version: {version!r}")

    numeric = re.split(r"[-.]", version.strip())[:3]

    return tuple(int(p) for p in numeric)  # type: ignore[return-value]


def at_least(version: str, minimum: str) -> bool:
    """Is `version` at or above `minimum`?"""
    return parts(version) >= parts(minimum)
