#!/usr/bin/env python3
"""
构建脚本 - 将Python Core打包成独立可执行文件
"""

import os
import sys
import subprocess
import shutil
import platform
from pathlib import Path

def get_project_root():
    """获取项目根目录"""
    current_file = Path(__file__).resolve()
    # 从 scripts/build_python_core.py 回到项目根目录
    return current_file.parent.parent

def install_dependencies():
    """安装构建依赖"""
    print("📦 Installing build dependencies...")
    
    dependencies = [
        'pyinstaller>=5.0',
        'requests',
        'Pillow',
        'opencv-python-headless',  # 使用headless版本减少依赖
    ]
    
    for dep in dependencies:
        print(f"Installing {dep}...")
        result = subprocess.run([
            sys.executable, '-m', 'pip', 'install', dep
        ], capture_output=True, text=True)
        
        if result.returncode != 0:
            print(f"❌ Failed to install {dep}")
            print(result.stderr)
            return False
        else:
            print(f"✅ Installed {dep}")
    
    return True

def clean_build_directory(python_core_dir):
    """清理构建目录"""
    print("🧹 Cleaning build directories...")
    
    dirs_to_clean = ['build', 'dist', '__pycache__']
    
    for dir_name in dirs_to_clean:
        dir_path = python_core_dir / dir_name
        if dir_path.exists():
            shutil.rmtree(dir_path)
            print(f"Removed {dir_path}")

def build_executable(python_core_dir, use_simple=False):
    """构建可执行文件"""
    print("🔨 Building executable...")

    if use_simple:
        spec_file = python_core_dir / 'build_simple.spec'
        print("Using simplified build for testing...")
    else:
        spec_file = python_core_dir / 'build.spec'

    if not spec_file.exists():
        print(f"❌ Spec file not found: {spec_file}")
        return False
    
    # 运行PyInstaller
    cmd = [
        sys.executable, '-m', 'PyInstaller',
        '--clean',
        '--noconfirm',
        str(spec_file)
    ]
    
    print(f"Running: {' '.join(cmd)}")
    
    result = subprocess.run(
        cmd,
        cwd=python_core_dir,
        capture_output=True,
        text=True
    )
    
    if result.returncode != 0:
        print("❌ Build failed!")
        print("STDOUT:", result.stdout)
        print("STDERR:", result.stderr)
        return False
    
    print("✅ Build completed successfully!")
    return True

def copy_to_sidecar_directory(project_root, python_core_dir):
    """复制可执行文件到Tauri sidecar目录"""
    print("📁 Copying executable to sidecar directory...")
    
    # 确定可执行文件名
    system = platform.system().lower()
    if system == 'windows':
        exe_name = 'mixvideo-python-core.exe'
    else:
        exe_name = 'mixvideo-python-core'
    
    # 源文件路径
    source_exe = python_core_dir / 'dist' / exe_name
    
    if not source_exe.exists():
        print(f"❌ Executable not found: {source_exe}")
        return False
    
    # 目标目录
    sidecar_dir = project_root / 'src-tauri' / 'binaries'
    sidecar_dir.mkdir(exist_ok=True)
    
    # 复制文件
    target_exe = sidecar_dir / exe_name
    shutil.copy2(source_exe, target_exe)
    
    # 在Unix系统上设置执行权限
    if system != 'windows':
        os.chmod(target_exe, 0o755)
    
    print(f"✅ Copied to: {target_exe}")
    return True

def update_tauri_config(project_root):
    """更新Tauri配置文件以包含sidecar"""
    print("⚙️ Updating Tauri configuration...")
    
    import json
    
    config_file = project_root / 'src-tauri' / 'tauri.conf.json'
    
    if not config_file.exists():
        print(f"❌ Tauri config not found: {config_file}")
        return False
    
    # 读取配置
    with open(config_file, 'r', encoding='utf-8') as f:
        config = json.load(f)
    
    # 添加sidecar配置
    if 'bundle' not in config:
        config['bundle'] = {}
    
    if 'externalBin' not in config['bundle']:
        config['bundle']['externalBin'] = []
    
    # 检查是否已经存在
    sidecar_name = 'mixvideo-python-core'
    existing = any(
        item.get('name') == sidecar_name 
        for item in config['bundle']['externalBin']
        if isinstance(item, dict)
    )
    
    if not existing:
        config['bundle']['externalBin'].append({
            "name": sidecar_name,
            "src": f"binaries/{sidecar_name}",
            "targets": ["all"]
        })
        
        # 写回配置
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(config, f, indent=2, ensure_ascii=False)
        
        print("✅ Updated Tauri configuration")
    else:
        print("ℹ️ Sidecar already configured in Tauri")
    
    return True

def verify_build(project_root):
    """验证构建结果"""
    print("🔍 Verifying build...")
    
    system = platform.system().lower()
    exe_name = 'mixvideo-python-core.exe' if system == 'windows' else 'mixvideo-python-core'
    
    sidecar_exe = project_root / 'src-tauri' / 'binaries' / exe_name
    
    if not sidecar_exe.exists():
        print(f"❌ Sidecar executable not found: {sidecar_exe}")
        return False
    
    # 测试执行
    try:
        result = subprocess.run([
            str(sidecar_exe), '--version'
        ], capture_output=True, text=True, timeout=10)
        
        if result.returncode == 0:
            print("✅ Executable is working correctly")
            print(f"Version output: {result.stdout.strip()}")
            return True
        else:
            print(f"❌ Executable test failed: {result.stderr}")
            return False
            
    except subprocess.TimeoutExpired:
        print("❌ Executable test timed out")
        return False
    except Exception as e:
        print(f"❌ Executable test error: {e}")
        return False

def main():
    """主函数"""
    print("🚀 Building MixVideo V2 Python Core...")
    
    project_root = get_project_root()
    python_core_dir = project_root / 'python_core'
    
    print(f"Project root: {project_root}")
    print(f"Python core directory: {python_core_dir}")
    
    if not python_core_dir.exists():
        print(f"❌ Python core directory not found: {python_core_dir}")
        sys.exit(1)
    
    # 步骤1: 安装依赖
    if not install_dependencies():
        print("❌ Failed to install dependencies")
        sys.exit(1)
    
    # 步骤2: 清理构建目录
    clean_build_directory(python_core_dir)
    
    # 步骤3: 构建可执行文件
    # 首先尝试简化版本
    print("Trying simplified build first...")
    if not build_executable(python_core_dir, use_simple=True):
        print("❌ Simplified build failed, trying full build...")
        if not build_executable(python_core_dir, use_simple=False):
            print("❌ Failed to build executable")
            sys.exit(1)
    
    # 步骤4: 复制到sidecar目录
    if not copy_to_sidecar_directory(project_root, python_core_dir):
        print("❌ Failed to copy executable")
        sys.exit(1)
    
    # 步骤5: 更新Tauri配置
    if not update_tauri_config(project_root):
        print("❌ Failed to update Tauri configuration")
        sys.exit(1)
    
    # 步骤6: 验证构建
    if not verify_build(project_root):
        print("❌ Build verification failed")
        sys.exit(1)
    
    print("🎉 Build completed successfully!")
    print("\n📋 Next steps:")
    print("1. Test the sidecar: cargo tauri dev")
    print("2. Build the app: cargo tauri build")
    print("3. The Python core will be bundled with your app")

if __name__ == "__main__":
    main()
