"""版本工具函数，在构建端（开发机）和应用端（离线机）共享

Provides version tracking and git change detection utilities.
All functions work standalone without Django imports.
"""
from pathlib import Path
import subprocess
import re

PROJECT_DIR = Path(__file__).resolve().parent.parent
VERSION_FILE = PROJECT_DIR / 'VERSION'


def get_current_version() -> str:
    """从 VERSION 文件读取当前版本"""
    if VERSION_FILE.exists():
        return VERSION_FILE.read_text(encoding='utf-8').strip()
    return 'v0.0.0'


def set_current_version(version: str) -> None:
    """写入 VERSION 文件"""
    VERSION_FILE.write_text(version.strip() + '\n', encoding='utf-8')


def get_git_tags() -> list[str]:
    """获取所有 git tag，按版本号降序排列"""
    try:
        result = subprocess.run(
            ['git', 'tag', '--sort=-version:refname'],
            capture_output=True, text=True, cwd=PROJECT_DIR, timeout=30
        )
        return [t.strip() for t in result.stdout.strip().split('\n') if t.strip()]
    except (subprocess.TimeoutExpired, FileNotFoundError):
        return []


def get_latest_tag() -> str | None:
    """获取最新 git tag，如果没有则返回 None"""
    tags = get_git_tags()
    return tags[0] if tags else None


def get_changed_files(from_tag: str, to_ref: str = 'HEAD') -> tuple[list[str], list[str]]:
    """获取两个 git 引用之间变更的文件列表

    使用 git diff --name-status 以确保能捕获删除的文件。

    Args:
        from_tag: 起始版本（如 'v1.0'）
        to_ref: 终止引用（默认 HEAD）

    Returns:
        (added_modified: list[str], deleted: list[str])
        文件路径相对于项目根目录
    """
    try:
        result = subprocess.run(
            ['git', 'diff', '--name-status', f'{from_tag}..{to_ref}'],
            capture_output=True, text=True, cwd=PROJECT_DIR, timeout=30
        )
    except (subprocess.TimeoutExpired, FileNotFoundError):
        return [], []

    added_modified: list[str] = []
    deleted: list[str] = []

    for line in result.stdout.strip().split('\n'):
        if not line.strip():
            continue
        parts = line.split('\t')
        if len(parts) < 2:
            continue
        status = parts[0]
        path = parts[1]

        # Handle renames: R100 file1\tfile2 → track the new name
        if status.startswith('R'):
            if len(parts) >= 3:
                added_modified.append(parts[2])  # new name
                deleted.append(parts[1])          # old name
            continue

        if status == 'D':
            deleted.append(path)
        elif status in ('A', 'M', 'C'):
            added_modified.append(path)

    return added_modified, deleted


def is_working_tree_clean() -> bool:
    """检查 git 工作树是否干净（无未提交变更）"""
    try:
        result = subprocess.run(
            ['git', 'diff', '--stat'],
            capture_output=True, text=True, cwd=PROJECT_DIR, timeout=15
        )
        return result.stdout.strip() == ''
    except (subprocess.TimeoutExpired, FileNotFoundError):
        return False


def bump_version(current: str) -> str:
    """递增版本号
    
    v0.0.0 → v1.0 (首次稳定版)
    v1.0 → v1.1
    v1.9 → v1.10
    v1.1.2 → v1.1.3
    v1.1.9 → v1.1.10
    """
    match = re.match(r'v(\d+)\.(\d+)(?:\.(\d+))?', current)
    if not match:
        return 'v1.0'
    major = int(match.group(1))
    minor = int(match.group(2))
    patch = match.group(3)
    if major == 0:
        return 'v1.0'
    if patch is not None:
        # 3-segment: increment patch
        return f'v{major}.{minor}.{int(patch) + 1}'
    else:
        # 2-segment: increment minor
        return f'v{major}.{minor + 1}'


if __name__ == '__main__':
    print(bump_version('v1.1.2'))
