"""
core/version.py - 版本管理
==========================
集中管理 MyAgent 版本号，供所有模块引用。
单一数据源: package.json
支持从 package.json / 环境变量 动态获取版本。
"""
from __future__ import annotations

import json
import os
import subprocess
from pathlib import Path


def _version_from_package_json() -> str:
    """从 package.json 读取版本号（单一数据源）
    
    npm 全局安装时，包结构为:
      /usr/lib/node_modules/myagent-ai/        ← 根 package.json (npm bin 入口)
      /usr/lib/node_modules/myagent-ai/myagent/  ← 子目录 package.json (代码)
    
    Python 代码运行时 sys.path 包含 myagent/ 子目录，
    Path(__file__).parent.parent 找到的是 myagent/package.json。
    但根 package.json 才是 npm 管理的版本号（single source of truth）。
    
    策略: 同时查找两层 package.json，优先取有更高版本号的。
    """
    candidates = [
        Path(__file__).parent.parent / "package.json",       # myagent/package.json
        Path(__file__).parent.parent.parent / "package.json", # 根 package.json
    ]
    best = ""
    for pkg_path in candidates:
        try:
            if pkg_path.exists():
                data = json.loads(pkg_path.read_text(encoding="utf-8"))
                ver = data.get("version", "")
                if ver:
                    # 取较高的版本号
                    if not best or _ver_tuple(ver) > _ver_tuple(best):
                        best = ver
        except Exception:
            pass
    return best


def _ver_tuple(v: str) -> tuple:
    """将版本字符串转为可比较的 tuple，如 '1.25.7' → (1, 25, 7)"""
    try:
        return tuple(int(x) for x in v.split(".")[:3])
    except (ValueError, AttributeError):
        return (0, 0, 0)


def _version_from_git() -> str:
    """尝试从 git describe 获取版本号（必须是 x.y.z 格式）"""
    try:
        result = subprocess.run(
            ["git", "describe", "--tags", "--always", "--dirty"],
            capture_output=True, text=True, timeout=3,
            cwd=Path(__file__).parent.parent,
        )
        tag = result.stdout.strip()
        if tag:
            # 去掉 'v' 前缀
            tag = tag.lstrip("v")
            # 只接受 x.y.z 格式的版本号，拒绝 commit hash
            if tag and tag[0].isdigit() and "." in tag:
                # 去掉 dirty 标记和 build metadata
                clean = tag.split("-dirty")[0].split("+")[0]
                return clean
    except Exception:
        pass
    return ""


def get_version() -> str:
    """获取当前版本号。

    优先级: 环境变量 MYAGENT_VERSION > package.json > git tag
    """
    env_ver = os.environ.get("MYAGENT_VERSION", "").strip()
    if env_ver:
        return env_ver
    pkg_ver = _version_from_package_json()
    if pkg_ver:
        return pkg_ver
    git_ver = _version_from_git()
    if git_ver:
        return git_ver
    # 最后的 fallback — 不应该走到这里
    return "0.0.0"


# 导出给外部使用
__version__ = get_version()
