#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
云盘后端Linux打包脚本
使用PyInstaller将后端应用打包成Linux可执行文件
"""

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

def check_python_version():
    """检查Python版本"""
    if sys.version_info < (3, 8):
        print("错误: 需要Python 3.8或更高版本")
        sys.exit(1)
    print(f"[OK] Python版本: {sys.version}")

def check_dependencies():
    """检查必要的依赖"""
    try:
        import PyInstaller
        print(f"[OK] PyInstaller版本: {PyInstaller.__version__}")
    except ImportError:
        print("错误: 未安装PyInstaller")
        print("请运行: pip install pyinstaller")
        sys.exit(1)

def clean_build_dirs():
    """清理之前的构建目录"""
    dirs_to_clean = ['build', 'dist', '__pycache__']
    for dir_name in dirs_to_clean:
        if os.path.exists(dir_name):
            print(f"清理目录: {dir_name}")
            shutil.rmtree(dir_name)

    # 清理Python缓存文件
    for root, dirs, files in os.walk('.'):
        for file in files:
            if file.endswith('.pyc') or file.endswith('.pyo'):
                os.remove(os.path.join(root, file))
        if '__pycache__' in dirs:
            shutil.rmtree(os.path.join(root, '__pycache__'))

def create_spec_file():
    """创建或更新PyInstaller规格文件"""
    # 直接使用现有的build.spec文件
    print("[OK] build.spec 文件已存在，跳过创建")

def run_pyinstaller():
    """运行PyInstaller进行打包"""
    print("开始打包...")
    try:
        # 使用spec文件进行打包
        cmd = ['pyinstaller', '--clean', 'build.spec']
        result = subprocess.run(cmd, check=True, capture_output=True, text=True)
        print("[OK] PyInstaller执行成功")
        if result.stdout:
            print("输出:", result.stdout)
    except subprocess.CalledProcessError as e:
        print(f"错误: PyInstaller执行失败: {e}")
        if e.stderr:
            print("错误输出:", e.stderr)
        sys.exit(1)

def create_deployment_package():
    """创建部署包"""
    dist_dir = Path('dist')
    deploy_dir = Path('deploy')

    if deploy_dir.exists():
        shutil.rmtree(deploy_dir)

    deploy_dir.mkdir()

    # 复制可执行文件
    exe_file = dist_dir / 'cloud-drive-server'
    if exe_file.exists():
        shutil.copy2(exe_file, deploy_dir)
        print(f"[OK] 复制可执行文件到 {deploy_dir}")

    # 复制配置文件
    config_files = ['.env.example']
    for config_file in config_files:
        if os.path.exists(config_file):
            shutil.copy2(config_file, deploy_dir)
            print(f"[OK] 复制配置文件 {config_file}")

    # 复制安装脚本
    install_scripts = ['install.sh', 'install_user.sh']
    for script in install_scripts:
        if os.path.exists(script):
            shutil.copy2(script, deploy_dir)
            os.chmod(deploy_dir / script, 0o755)
            print(f"[OK] 复制安装脚本 {script}")

    # 创建部署目录结构
    (deploy_dir / 'logs').mkdir(exist_ok=True)
    (deploy_dir / 'uploads').mkdir(exist_ok=True)

    # 创建启动脚本
    create_startup_script(deploy_dir)

    # 创建README
    create_readme(deploy_dir)

    print(f"[OK] 部署包创建完成: {deploy_dir.absolute()}")

    deploy_dir.mkdir()

    # 复制可执行文件
    exe_file = dist_dir / 'cloud-drive-server'
    if exe_file.exists():
        shutil.copy2(exe_file, deploy_dir)
        print(f"[OK] 复制可执行文件到 {deploy_dir}")

    # 复制配置文件
    config_files = ['.env.example']
    for config_file in config_files:
        if os.path.exists(config_file):
            shutil.copy2(config_file, deploy_dir)
            print(f"[OK] 复制配置文件 {config_file}")

    # 创建部署目录结构
    (deploy_dir / 'logs').mkdir(exist_ok=True)
    (deploy_dir / 'uploads').mkdir(exist_ok=True)

    # 创建启动脚本
    create_startup_script(deploy_dir)

    # 创建README
    create_readme(deploy_dir)

    print(f"[OK] 部署包创建完成: {deploy_dir.absolute()}")

def create_startup_script(deploy_dir):
    """创建启动脚本"""
    # Linux启动脚本
    startup_script = '''#!/bin/bash
# 云盘后端服务启动脚本

# 设置环境变量
export PYTHONPATH=${PYTHONPATH}:$(dirname "$0")

# 进入脚本所在目录
cd "$(dirname "$0")"

# 检查环境文件
if [ ! -f ".env" ]; then
    echo "警告: .env 文件不存在，将使用默认配置"
    if [ -f ".env.example" ]; then
        cp .env.example .env
        echo "已复制 .env.example 为 .env，请根据需要修改配置"
    fi
fi

# 创建必要的目录
mkdir -p logs uploads

# 启动服务
echo "启动云盘后端服务..."
./cloud-drive-server
'''

    script_path = deploy_dir / 'start.sh'
    with open(script_path, 'w', encoding='utf-8') as f:
        f.write(startup_script)

    # 设置执行权限
    os.chmod(script_path, 0o755)
    print("[OK] 创建启动脚本 start.sh")

def create_readme(deploy_dir):
    """创建部署说明文档"""
    readme_content = '''# 云盘后端服务部署说明

## 文件说明

- `cloud-drive-server`: 主程序可执行文件
- `start.sh`: 启动脚本
- `.env.example`: 环境配置示例文件

## 快速开始

1. **配置环境变量**
   ```bash
   cp .env.example .env
   # 编辑 .env 文件，配置数据库和Redis连接信息
   nano .env
   ```

2. **启动服务**
   ```bash
   chmod +x start.sh
   ./start.sh
   ```

   或者直接运行：
   ```bash
   ./cloud-drive-server
   ```

3. **访问服务**
   - API文档: http://localhost:8000/docs
   - 健康检查: http://localhost:8000/api/v1/health

## 环境配置

主要配置项（.env文件）：

```env
# 数据库配置
DATABASE_URL=mysql+pymysql://用户名:密码@主机:端口/数据库名

# Redis配置
REDIS_URL=redis://主机:端口

# JWT配置
JWT_SECRET_KEY=你的密钥
JWT_EXPIRE_MINUTES=30

# 文件上传配置
UPLOAD_DIR=uploads
MAX_FILE_SIZE=10485760  # 10MB
```

## 系统要求

- Linux 64位系统
- MySQL 5.7+ 或 8.0+
- Redis (可选)
- 至少512MB内存
- 至少100MB磁盘空间

## 日志

日志文件位置：`logs/app.log`

## 问题排查

1. **端口占用**
   - 默认端口8000，如需修改请编辑.env文件

2. **数据库连接失败**
   - 检查DATABASE_URL配置
   - 确保数据库服务正在运行
   - 检查防火墙设置

3. **权限问题**
   - 确保程序有执行权限：`chmod +x cloud-drive-server`
   - 确保有写入logs和uploads目录的权限

## 后台运行

使用systemd或supervisor管理服务进程：

### systemd 配置示例

创建服务文件 `/etc/systemd/system/cloud-drive.service`：

```ini
[Unit]
Description=Cloud Drive Backend Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/deploy/directory
ExecStart=/path/to/deploy/directory/cloud-drive-server
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

启用和启动服务：
```bash
sudo systemctl daemon-reload
sudo systemctl enable cloud-drive
sudo systemctl start cloud-drive
```
'''

    readme_path = deploy_dir / 'README.md'
    with open(readme_path, 'w', encoding='utf-8') as f:
        f.write(readme_content)
    print("[OK] 创建部署说明文档 README.md")

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='云盘后端Linux打包工具')
    parser.add_argument('--clean', action='store_true', help='仅清理构建目录')
    parser.add_argument('--no-clean', action='store_true', help='跳过清理步骤')

    args = parser.parse_args()

    print("=== 云盘后端Linux打包工具 ===")
    print(f"当前目录: {os.getcwd()}")

    # 检查环境
    check_python_version()
    check_dependencies()

    # 清理构建目录
    if args.clean:
        clean_build_dirs()
        print("[OK] 清理完成")
        return

    if not args.no_clean:
        clean_build_dirs()

    # 创建规格文件
    create_spec_file()

    # 运行打包
    run_pyinstaller()

    # 创建部署包
    create_deployment_package()

    print("\n=== 打包完成 ===")
    print("部署包位置: ./deploy/")
    print("请查看 ./deploy/README.md 了解部署说明")

if __name__ == '__main__':
    main()