#!/usr/bin/env python3
"""
ccltt 包自动化构建和上传脚本

使用方法:
    python upload_package.py

功能:
    1. 清理构建缓存
    2. 运行测试
    3. 构建包
    4. 上传到 PyPI
    5. 验证上传结果
"""

import os
import sys
import subprocess
import time
import requests
from pathlib import Path

# PyPI 配置
PYPI_TOKEN_ENV = "PYPI_TOKEN"

def get_pypi_token() -> str:
    """
    从环境变量读取 PyPI token，避免把敏感信息硬编码进仓库。
    使用示例:
        export PYPI_TOKEN="pypi-xxx"
        python upload_package.py
    """
    token = os.environ.get(PYPI_TOKEN_ENV)
    if not token:
        print(f"❌ 未设置环境变量 {PYPI_TOKEN_ENV}，无法上传。")
        print(f"请先执行: export {PYPI_TOKEN_ENV}='pypi-***'  (或在你的CI里配置该环境变量)")
        sys.exit(1)
    return token

def run_command(cmd, description=""):
    """运行命令并处理输出"""
    print(f"\n🔄 {description}")
    print(f"执行命令: {cmd}")
    
    try:
        result = subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True)
        if result.stdout:
            print(f"输出: {result.stdout.strip()}")
        return True
    except subprocess.CalledProcessError as e:
        print(f"❌ 命令执行失败: {e}")
        if e.stdout:
            print(f"标准输出: {e.stdout}")
        if e.stderr:
            print(f"错误输出: {e.stderr}")
        return False

def get_current_version():
    """获取当前版本号"""
    about_file = Path("src/ccltt/__about__.py")
    if about_file.exists():
        with open(about_file, 'r', encoding='utf-8') as f:
            content = f.read()
            for line in content.split('\n'):
                if line.strip().startswith('__version__'):
                    version = line.split('"')[1]
                    return version
    return None

def verify_upload(version, max_retries=5):
    """验证上传是否成功"""
    print(f"\n🔍 验证版本 {version} 是否已上传到 PyPI...")
    
    for i in range(max_retries):
        try:
            response = requests.get('https://pypi.org/pypi/ccltt/json', timeout=10)
            if response.status_code == 200:
                data = response.json()
                latest_version = data["info"]["version"]
                if latest_version == version:
                    print(f"✅ 验证成功! PyPI 最新版本: {latest_version}")
                    return True
                else:
                    print(f"⏳ 当前 PyPI 版本: {latest_version}, 等待版本 {version}...")
            else:
                print(f"⚠️ HTTP 错误: {response.status_code}")
        except Exception as e:
            print(f"⚠️ 验证请求失败: {e}")
        
        if i < max_retries - 1:
            print(f"⏳ 等待 10 秒后重试... ({i+1}/{max_retries})")
            time.sleep(10)
    
    print(f"❌ 验证失败，版本 {version} 可能未成功上传")
    return False

def main():
    """主函数"""
    print("🚀 ccltt 包自动化构建和上传脚本")
    print("=" * 50)
    
    # 获取当前版本
    version = get_current_version()
    if not version:
        print("❌ 无法获取版本号")
        sys.exit(1)
    
    print(f"📦 当前版本: {version}")
    
    # 步骤 1: 清理构建缓存
    if not run_command("rm -rf dist/ build/ src/ccltt.egg-info/", "清理构建缓存"):
        print("❌ 清理失败")
        sys.exit(1)
    
    # 步骤 2: 运行测试
    if not run_command("python -m pytest tests/test_initial.py -v", "运行测试"):
        print("❌ 测试失败")
        sys.exit(1)
    
    # 步骤 3: 构建包
    if not run_command("python -m build", "构建包"):
        print("❌ 构建失败")
        sys.exit(1)
    
    # 步骤 4: 检查构建结果
    dist_files = list(Path("dist").glob("*.whl")) + list(Path("dist").glob("*.tar.gz"))
    if not dist_files:
        print("❌ 构建文件未找到")
        sys.exit(1)
    
    print(f"✅ 构建成功，生成文件:")
    for file in dist_files:
        print(f"  - {file.name}")
    
    # 步骤 5: 上传到 PyPI
    pypi_token = get_pypi_token()
    upload_cmd = f"python -m twine upload --username __token__ --password {pypi_token} dist/*"
    if not run_command(upload_cmd, "上传到 PyPI"):
        print("❌ 上传失败")
        sys.exit(1)
    
    # 步骤 6: 验证上传
    if verify_upload(version):
        print(f"\n🎉 成功完成! 版本 {version} 已上传到 PyPI")
        print(f"📋 PyPI 地址: https://pypi.org/project/ccltt/{version}/")
        print(f"📦 安装命令: pip install ccltt=={version}")
    else:
        print(f"\n⚠️ 上传可能成功，但验证失败。请手动检查 PyPI")
        sys.exit(1)

if __name__ == "__main__":
    main()
