#!/usr/bin/env python3
"""
检测依赖版本冲突
检查requirements-base.txt和requirements-extra.txt中是否有同一包的不同版本要求

用法:
    python scripts/check_version_conflict.py
"""

import re
import sys
from collections import defaultdict


def parse_requirements(filename):
    """解析requirements文件，返回{package: version_spec}"""
    packages = {}
    with open(filename, 'r') as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            # 提取包名（处理>=、==、~=等）
            match = re.match(r'^([a-zA-Z0-9_\-]+)\s*(.*)', line)
            if match:
                pkg_name = match.group(1).lower().replace('_', '-')
                version_spec = match.group(2)
                packages[pkg_name] = version_spec
    return packages


def main():
    import os
    script_dir = os.path.dirname(os.path.abspath(__file__))
    base_file = os.path.join(script_dir, '..', 'requirements-base.txt')
    extra_file = os.path.join(script_dir, '..', 'requirements-extra.txt')

    if not os.path.exists(base_file):
        print(f"❌ 未找到文件: {base_file}")
        return 1

    if not os.path.exists(extra_file):
        print(f"❌ 未找到文件: {extra_file}")
        return 1

    base = parse_requirements(base_file)
    extra = parse_requirements(extra_file)

    conflicts = []
    all_pkgs = defaultdict(list)

    for pkg, ver in base.items():
        all_pkgs[pkg].append(('base', ver))

    for pkg, ver in extra.items():
        all_pkgs[pkg].append(('extra', ver))

    for pkg, locations in all_pkgs.items():
        if len(locations) > 1:
            versions = [f"{file}: {ver}" for file, ver in locations]
            conflicts.append(f"  - {pkg}: {', '.join(versions)}")

    if conflicts:
        print("❌ 检测到版本冲突:")
        print("\n".join(conflicts))
        print(f"\n总计 {len(conflicts)} 个冲突，请解决后再构建")
        return 1
    else:
        print("✅ 未检测到版本冲突")
        print(f"   基础依赖: {len(base)} 包")
        print(f"   额外依赖: {len(extra)} 包")
        return 0


if __name__ == '__main__':
    sys.exit(main())
