@echo off
REM TSP智能助手快速更新脚本 (Windows)
REM 支持热更新和完整更新

setlocal enabledelayedexpansion

REM 颜色定义
set "GREEN=[32m"
set "YELLOW=[33m"
set "RED=[31m"
set "NC=[0m"

REM 配置变量
set "APP_NAME=tsp_assistant"
set "DEPLOY_PATH=."
set "BACKUP_PATH=.\backups"
set "HEALTH_URL=http://localhost:5000/api/health"

REM 解析参数
set "ACTION=%1"
set "SOURCE_PATH=%2"
set "ENVIRONMENT=%3"

if "%ACTION%"=="" (
    echo 用法: %0 {check^|hot-update^|full-update^|auto-update^|rollback} [源路径] [环境]
    echo.
    echo 命令说明:
    echo   check        - 检查更新可用性
    echo   hot-update   - 热更新（不重启服务）
    echo   full-update  - 完整更新（重启服务）
    echo   auto-update  - 自动更新（智能选择）
    echo   rollback     - 回滚到指定备份
    echo.
    echo 环境: development, staging, production
    exit /b 1
)

if "%ENVIRONMENT%"=="" set "ENVIRONMENT=production"
if "%SOURCE_PATH%"=="" set "SOURCE_PATH=."

REM 日志函数
:log_info
echo %GREEN%[INFO]%NC% %~1
goto :eof

:log_warn
echo %YELLOW%[WARN]%NC% %~1
goto :eof

:log_error
echo %RED%[ERROR]%NC% %~1
goto :eof

REM 检查更新可用性
:check_update
call :log_info "检查更新可用性..."
if not exist "%SOURCE_PATH%\version.json" (
    call :log_error "源路径中未找到版本文件"
    exit /b 1
)

REM 比较版本
for /f "tokens=2 delims=:" %%a in ('findstr "version" "%SOURCE_PATH%\version.json"') do (
    set "NEW_VERSION=%%a"
    set "NEW_VERSION=!NEW_VERSION: =!"
    set "NEW_VERSION=!NEW_VERSION:"=!"
    set "NEW_VERSION=!NEW_VERSION:,=!"
)

if exist "version.json" (
    for /f "tokens=2 delims=:" %%a in ('findstr "version" "version.json"') do (
        set "CURRENT_VERSION=%%a"
        set "CURRENT_VERSION=!CURRENT_VERSION: =!"
        set "CURRENT_VERSION=!CURRENT_VERSION:"=!"
        set "CURRENT_VERSION=!CURRENT_VERSION:,=!"
    )
) else (
    set "CURRENT_VERSION=unknown"
)

if "!NEW_VERSION!"=="!CURRENT_VERSION!" (
    call :log_info "没有更新可用 (当前版本: !CURRENT_VERSION!)"
) else (
    call :log_info "发现更新: !CURRENT_VERSION! -> !NEW_VERSION!"
)
goto :eof

REM 创建备份
:create_backup
set "TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
set "TIMESTAMP=!TIMESTAMP: =0!"
set "BACKUP_NAME=%APP_NAME%_backup_!TIMESTAMP!"

call :log_info "创建备份: !BACKUP_NAME!"

if not exist "%BACKUP_PATH%" mkdir "%BACKUP_PATH%"
mkdir "%BACKUP_PATH%\!BACKUP_NAME!"

REM 备份应用文件
if exist "%DEPLOY_PATH%" (
    call :log_info "备份应用文件..."
    xcopy "%DEPLOY_PATH%\*" "%BACKUP_PATH%\!BACKUP_NAME!\" /E /I /Y
)

REM 备份数据库
if exist "%DEPLOY_PATH%\tsp_assistant.db" (
    call :log_info "备份数据库..."
    mkdir "%BACKUP_PATH%\!BACKUP_NAME!\database"
    copy "%DEPLOY_PATH%\tsp_assistant.db" "%BACKUP_PATH%\!BACKUP_NAME!\database\"
)

call :log_info "备份完成: !BACKUP_NAME!"
echo !BACKUP_NAME!
goto :eof

REM 热更新
:hot_update
call :log_info "开始热更新..."

REM 支持热更新的文件列表
set "HOT_UPDATE_FILES=src\web\static\js\dashboard.js src\web\static\css\style.css src\web\templates\dashboard.html src\web\app.py"

set "UPDATED_COUNT=0"
for %%f in (%HOT_UPDATE_FILES%) do (
    if exist "%SOURCE_PATH%\%%f" (
        call :log_info "更新文件: %%f"
        if not exist "%DEPLOY_PATH%\%%f" mkdir "%DEPLOY_PATH%\%%f" 2>nul
        copy "%SOURCE_PATH%\%%f" "%DEPLOY_PATH%\%%f" /Y >nul
        set /a UPDATED_COUNT+=1
    )
)

if !UPDATED_COUNT! gtr 0 (
    call :log_info "热更新完成，更新了 !UPDATED_COUNT! 个文件"
) else (
    call :log_info "没有文件需要热更新"
)
goto :eof

REM 完整更新
:full_update
call :log_info "开始完整更新..."

REM 创建备份
call :create_backup
set "BACKUP_NAME=!BACKUP_NAME!"

REM 停止服务（如果运行中）
call :log_info "停止服务..."
taskkill /f /im python.exe 2>nul || echo 服务未运行

REM 更新文件
call :log_info "更新应用文件..."
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
mkdir "%DEPLOY_PATH%"
xcopy "%SOURCE_PATH%\*" "%DEPLOY_PATH%\" /E /I /Y

REM 安装依赖
call :log_info "安装依赖..."
cd "%DEPLOY_PATH%"
if exist "requirements.txt" (
    pip install -r requirements.txt
)

REM 运行数据库迁移
call :log_info "运行数据库迁移..."
if exist "init_database.py" (
    python init_database.py
)

REM 启动服务
call :log_info "启动服务..."
start /b python start_dashboard.py

REM 等待服务启动
call :log_info "等待服务启动..."
timeout /t 15 /nobreak >nul

REM 健康检查
call :log_info "执行健康检查..."
set "RETRY_COUNT=0"
set "MAX_RETRIES=10"

:health_check_loop
if !RETRY_COUNT! geq !MAX_RETRIES! (
    call :log_error "健康检查失败，开始回滚..."
    call :rollback !BACKUP_NAME!
    exit /b 1
)

curl -f "%HEALTH_URL%" >nul 2>&1
if !errorlevel! equ 0 (
    call :log_info "健康检查通过！"
    call :log_info "更新成功！"
    call :log_info "备份名称: !BACKUP_NAME!"
    exit /b 0
) else (
    call :log_warn "健康检查失败，重试中... (!RETRY_COUNT!/!MAX_RETRIES!)"
    set /a RETRY_COUNT+=1
    timeout /t 5 /nobreak >nul
    goto :health_check_loop
)

REM 回滚
:rollback
set "BACKUP_NAME=%1"
if "%BACKUP_NAME%"=="" (
    call :log_error "请指定备份名称"
    exit /b 1
)

call :log_info "开始回滚到备份: !BACKUP_NAME!"

if not exist "%BACKUP_PATH%\!BACKUP_NAME!" (
    call :log_error "备份不存在: !BACKUP_NAME!"
    exit /b 1
)

REM 停止服务
call :log_info "停止服务..."
taskkill /f /im python.exe 2>nul || echo 服务未运行

REM 恢复文件
call :log_info "恢复文件..."
if exist "%DEPLOY_PATH%" rmdir /s /q "%DEPLOY_PATH%"
mkdir "%DEPLOY_PATH%"
xcopy "%BACKUP_PATH%\!BACKUP_NAME!\*" "%DEPLOY_PATH%\" /E /I /Y

REM 恢复数据库
if exist "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" (
    call :log_info "恢复数据库..."
    copy "%BACKUP_PATH%\!BACKUP_NAME!\database\tsp_assistant.db" "%DEPLOY_PATH%\"
)

REM 启动服务
call :log_info "启动服务..."
cd "%DEPLOY_PATH%"
start /b python start_dashboard.py

REM 等待服务启动
timeout /t 15 /nobreak >nul

REM 健康检查
curl -f "%HEALTH_URL%" >nul 2>&1
if !errorlevel! equ 0 (
    call :log_info "回滚成功！"
) else (
    call :log_error "回滚后健康检查失败"
    exit /b 1
)
goto :eof

REM 自动更新
:auto_update
call :log_info "开始自动更新..."

REM 尝试热更新
call :hot_update
if !errorlevel! equ 0 (
    call :log_info "热更新成功"
    exit /b 0
)

REM 热更新失败，进行完整更新
call :log_info "热更新失败，进行完整更新..."
call :full_update
goto :eof

REM 主逻辑
if "%ACTION%"=="check" (
    call :check_update
) else if "%ACTION%"=="hot-update" (
    call :hot_update
) else if "%ACTION%"=="full-update" (
    call :full_update
) else if "%ACTION%"=="auto-update" (
    call :auto_update
) else if "%ACTION%"=="rollback" (
    call :rollback "%SOURCE_PATH%"
) else (
    call :log_error "未知操作: %ACTION%"
    exit /b 1
)

endlocal
