#Requires -Version 5.1
# EasyAI Windows 更新脚本
# 拉取仓库最新代码，更新镜像并重启服务
# 用法: .\update.ps1

# 设置控制台编码为 UTF-8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8

$ErrorActionPreference = "Stop"
$script:LogDir = $PSScriptRoot
if (-not $script:LogDir) { $script:LogDir = $env:TEMP }
$script:LogFile = Join-Path $script:LogDir "update.ps1.log"

function Write-Log {
    param([string]$Msg)
    try {
        $line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Msg"
        Add-Content -Path $script:LogFile -Value $line -Encoding UTF8 -ErrorAction SilentlyContinue
    } catch { }
}

trap {
    $errMsg = $_.Exception.Message
    try {
        Add-Content -Path $script:LogFile -Value "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 错误: $errMsg" -Encoding UTF8 -ErrorAction SilentlyContinue
    } catch { }
    Write-Host ""
    Write-Host "发生错误: $errMsg" -ForegroundColor Red
    if ($env:CI -ne "true") { Read-Host "按 Enter 键退出" }
    exit 1
}

function Wait-ForExit {
    if ($env:CI -eq "true") { return }
    Write-Host ""
    Read-Host "按 Enter 键退出"
}

function Write-Step { param($Msg) Write-Host $Msg }
function Write-Ok   { param($Msg) Write-Host "   ✓ $Msg" -ForegroundColor Green }
function Write-Err  { param($Msg) Write-Host "❌ $Msg" -ForegroundColor Red; throw $Msg }
function Write-Warn { param($Msg) Write-Host "⚠️ $Msg" -ForegroundColor Yellow }

# -h/--help
if ($args -contains "-h" -or $args -contains "--help") {
    Write-Host "用法: .\update.ps1"
    Write-Host ""
    Write-Host "脚本将提示选择更新方式，默认拉取仓库并更新镜像。"
    exit 0
}

# 进入项目目录
$scriptDir = $PSScriptRoot
if (-not $scriptDir) { Write-Err "无法获取脚本所在目录" }
$composePath = Join-Path $scriptDir "docker-compose.yml"
if (-not (Test-Path $composePath)) { Write-Err "未找到 docker-compose.yml，请在 easyai 目录下运行 update.ps1" }
Set-Location $scriptDir
Write-Step "📁 项目目录: $scriptDir"

# ==================== 命令行内选择 ====================
Write-Host ""
Write-Host "请选择更新方式："
Write-Host "   [1] 更新并拉取仓库（git pull）+ 更新镜像并重启（默认）"
Write-Host "   [2] 仅更新镜像并重启（跳过 git pull）"
$choice = Read-Host "请选择 [1/2，回车默认 1]"
if ([string]::IsNullOrWhiteSpace($choice)) { $choice = "1" }

$skipRepoUpdate = $false
switch ($choice) {
    "2" { $skipRepoUpdate = $true }
    "1" { }
    default {
        Write-Warn "无效选择，将使用默认：更新并拉取仓库"
        $skipRepoUpdate = $false
    }
}

# ==================== 拉取仓库 ====================
if (-not $skipRepoUpdate) {
    Write-Host ""
    Write-Host "==========================="
    Write-Host "📥 拉取仓库最新代码"
    Write-Host "==========================="

    if (-not (Test-Path ".git")) {
        Write-Err "当前目录不是 Git 仓库，请使用 git clone 克隆项目后使用 update.ps1"
    }

    Write-Step "📥 正在执行 git pull..."
    try {
        $output = git pull 2>&1
        if ($LASTEXITCODE -ne 0) { throw "git pull 返回 $LASTEXITCODE" }
        Write-Ok "仓库已更新到最新版本"
    } catch {
        Write-Err "git pull 失败，请检查网络或远程仓库配置"
    }

    # 确保环境配置文件存在
    Write-Host ""
    Write-Step "📝 检查环境配置文件..."
    if (-not (Test-Path ".env") -and (Test-Path ".env.sample")) {
        Copy-Item ".env.sample" ".env"
        Write-Ok ".env"
    }
    if (-not (Test-Path ".env.tools") -and (Test-Path ".env.tools.sample")) {
        Copy-Item ".env.tools.sample" ".env.tools"
        Write-Ok ".env.tools"
    }
    if (-not (Test-Path ".env.ASG") -and (Test-Path ".env.ASG.sample")) {
        Copy-Item ".env.ASG.sample" ".env.ASG"
        Write-Ok ".env.ASG"
    }
    if (-not (Test-Path ".env.AMS") -and (Test-Path ".env.AMS.sample")) {
        Copy-Item ".env.AMS.sample" ".env.AMS"
        Write-Ok ".env.AMS"
    }

    Write-Host ""
} else {
    Write-Host ""
    Write-Step "⏭️ 跳过仓库更新，仅更新镜像并重启"
    Write-Host ""
}

# ==================== Docker 检查 ====================
function Test-DockerInstalled {
    $docker = Get-Command docker -ErrorAction SilentlyContinue
    if (-not $docker) { return $false }
    try { $null = & docker --version 2>&1; return $true } catch { return $false }
}

function Test-DockerRunning {
    param([int]$TimeoutSeconds = 10)
    try {
        $psi = New-Object System.Diagnostics.ProcessStartInfo
        $psi.FileName = "docker"; $psi.Arguments = "info"
        $psi.RedirectStandardOutput = $true; $psi.RedirectStandardError = $true
        $psi.UseShellExecute = $false; $psi.CreateNoWindow = $true
        $p = [System.Diagnostics.Process]::Start($psi)
        $exited = $p.WaitForExit($TimeoutSeconds * 1000)
        if (-not $exited) { try { $p.Kill() } catch { }; return $false }
        return ($p.ExitCode -eq 0)
    } catch { return $false }
}

function Ensure-DockerRunning {
    if (-not (Test-DockerInstalled)) { return $false }
    if (Test-DockerRunning) {
        Write-Ok "Docker 引擎已运行"
        $v = docker --version 2>$null; if ($v) { Write-Host "   $v" }
        return $true
    }
    Write-Warn "Docker 未运行，请手动启动 Docker Desktop 后重新执行"
    return $false
}

Write-Host "==========================="
Write-Host "🚀 检查 Docker"
Write-Host "==========================="
Write-Host ""

if (-not (Test-DockerInstalled)) {
    Write-Err "未检测到 Docker，请先运行 start.ps1 完成首次部署"
}

if (-not (Ensure-DockerRunning)) {
    Write-Host ""
    Write-Host "请启动 Docker Desktop，确认其完全就绪后再重新运行 update.ps1"
    Wait-ForExit
    exit 1
}

# 检测 docker compose
$hasComposeV2 = $false
try { $null = docker compose version 2>&1; $hasComposeV2 = $true } catch { }

# ==================== 更新并启动 ====================
Write-Host ""
Write-Step "🚀 重新启动 EasyAI..."
if ($hasComposeV2) {
    docker compose pull
    if ($LASTEXITCODE -ne 0) { Write-Err "docker compose pull 失败" }
    docker compose up -d
    if ($LASTEXITCODE -ne 0) { Write-Err "docker compose up 失败" }
} else {
    docker-compose pull
    if ($LASTEXITCODE -ne 0) { Write-Err "docker-compose pull 失败" }
    docker-compose up -d
    if ($LASTEXITCODE -ne 0) { Write-Err "docker-compose up 失败" }
}

Write-Host ""
Write-Host "================================"
Write-Host "  更新完成"
Write-Host "================================"
Write-Host "🎉 EasyAI 应用更新成功"
Write-Host "访问地址: http://127.0.0.1:3010"
Write-Host ""
Write-Log "=== 更新完成 ==="
Wait-ForExit
