"""
语义版本解析与校验，用于客户端分发的 version_code（如 1.2.3）。
"""
import re
from typing import Tuple

# 允许：x / x.y / x.y.z，可选 -prerelease 后缀；前导 v 可选
VERSION_CODE_PATTERN = re.compile(
    r"^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:[-.]([a-zA-Z0-9.-]+))?$",
    re.IGNORECASE,
)


def parse_version_code(version_code: str) -> Tuple[int, int, int, str]:
    """
    将 version_code 解析为可比较元组 (major, minor, patch, prerelease)。
    不符合格式的返回 (0, 0, 0, raw)，保证可排序。
    """
    if not version_code or not isinstance(version_code, str):
        return (0, 0, 0, "")
    s = version_code.strip()
    m = VERSION_CODE_PATTERN.match(s)
    if not m:
        return (0, 0, 0, s)
    major = int(m.group(1))
    minor = int(m.group(2)) if m.group(2) else 0
    patch = int(m.group(3)) if m.group(3) else 0
    prerelease = (m.group(4) or "").strip()
    return (major, minor, patch, prerelease)


def version_sort_key(version_code: str) -> Tuple[int, int, int, str]:
    """用于 sorted(key=...) 的排序键。"""
    return parse_version_code(version_code)


def validate_version_code(version_code: str) -> None:
    """校验 version_code 格式，不符合则抛出 ValueError。"""
    if not version_code or not isinstance(version_code, str):
        raise ValueError("版本号不能为空")
    s = version_code.strip()
    if len(s) > 32:
        raise ValueError("版本号长度不能超过 32 字符")
    if not VERSION_CODE_PATTERN.match(s):
        raise ValueError(
            "版本号格式应为数字版本，如 1、1.2、1.2.3，可选 -prerelease 后缀（如 1.0.0-beta）"
        )
