<#
.SYNOPSIS
    MinIO 免 Alias 批量下载脚本 (强力兼容特殊字符版)。
.DESCRIPTION
    1. 采用临时配置目录 (--config-dir)，彻底解决密码中 #、@、$ 等符号导致的 URL 解析错误。
    2. 自动清理：脚本结束或异常退出时，会自动销毁临时生成的凭证文件。
    3. 路径追踪：支持递归下载、进度显示及失败文件自动清理。
#>

# =====================================================================
# 1. 解决中文编码问题
# =====================================================================
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding  = [System.Text.Encoding]::UTF8
$OutputEncoding           = [System.Text.Encoding]::UTF8

# =====================================================================
# 2. 变量配置区 (请按实际情况修改)
# =====================================================================
# MinIO 客户端 (mc.exe) 的全路径
$McExePath        = "C:\Users\zzy\Desktop\cmii\mc.exe"

# 远端服务器信息
$MinioEndpoint    = "https://oss.demo.uavcmlc.com"
$MinioUsername    = "cmii"
# 注意：密码务必使用单引号 '' 包裹，防止 PowerShell 误解析其中的特殊符号
$MinioPassword    = 'B#923fC7mk' 

# 远端桶及目录 (需以 / 结尾)
$TargetBucketPath = "cmlc-installation/rke13014/"

# 本地保存全路径 (需以 \ 结尾)
$LocalSavePath    = "C:\Users\zzy\Desktop\cmii\rke13014\"

# =====================================================================
# 3. 初始化临时环境 (避开环境变量 URL 解析 Bug)
# =====================================================================
Clear-Host
Write-Host "正在初始化安全传输环境..." -ForegroundColor Cyan

# 在系统临时目录下创建一个独立的 mc 配置文件夹
$TempConfigDir = Join-Path -Path $env:TEMP -ChildPath ("mc_tmp_" + [Guid]::NewGuid().ToString().Substring(0,8))
if (-not (Test-Path $TempConfigDir)) { New-Item -ItemType Directory -Path $TempConfigDir | Out-Null }

# 定义一个内部使用的临时 Alias 名称
$TmpAlias = "InternalTmp"

# =====================================================================
# 4. 建立连接 (使用 --config-dir 隔离配置)
# =====================================================================
Write-Host "正在建立与远端服务器的验证连接..." -ForegroundColor DarkGray

# 使用 alias set 命令，这种方式对密码中的 # 号等字符支持最稳健
& $McExePath --config-dir $TempConfigDir alias set $TmpAlias $MinioEndpoint $MinioUsername $MinioPassword --insecure | Out-Null

if ($LASTEXITCODE -ne 0) {
    Write-Error "验证失败！请检查账密（特别是特殊字符）或网络地址。"
    Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
    exit
}

# 拼接 mc 识别路径
$RemoteDir = "$TmpAlias/$TargetBucketPath"

# 检查本地目录
if (-not (Test-Path $LocalSavePath)) {
    New-Item -ItemType Directory -Path $LocalSavePath -Force | Out-Null
}

# =====================================================================
# 5. 安全获取文件列表
# =====================================================================
Write-Host "正在扫描远端文件..." -ForegroundColor Cyan
$jsonOutput = & $McExePath --config-dir $TempConfigDir ls --recursive --json --insecure $RemoteDir 2>&1

$fileList = @()
foreach ($line in $jsonOutput) {
    if ([string]::IsNullOrWhiteSpace($line) -or $line -match "mc: ") { continue }
    try {
        $obj = $line | ConvertFrom-Json -ErrorAction Stop
        if ($obj.type -eq "file") { $fileList += $obj }
    } catch { 
        # 忽略非 JSON 的提示信息
    }
}

$totalFiles = $fileList.Count
if ($totalFiles -eq 0) {
    Write-Host "未发现可下载文件，请检查桶路径是否正确: $TargetBucketPath" -ForegroundColor Yellow
    Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
    exit
}

# =====================================================================
# 6. 循环下载与断点清理
# =====================================================================
Write-Host "共扫描到 $totalFiles 个文件，开始下载任务..." -ForegroundColor Green

$currentIndex = 0
foreach ($file in $fileList) {
    $currentIndex++
    $relPath = $file.key
    $remoteFile = "$RemoteDir$relPath"
    
    # 路径转换
    $winRelPath = $relPath -replace '/', '\'
    $localFile = Join-Path -Path $LocalSavePath -ChildPath $winRelPath
    
    # 创建子目录
    $parentDir = Split-Path $localFile -Parent
    if (-not (Test-Path $parentDir)) { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null }

    Write-Host "[$currentIndex/$totalFiles] 正在下载: $relPath" -ForegroundColor Yellow
    
    # 执行下载
    & $McExePath --config-dir $TempConfigDir cp --insecure $remoteFile $localFile

    if ($LASTEXITCODE -ne 0) {
        Write-Host "  [失败] 下载被中断。" -ForegroundColor Red
        if (Test-Path $localFile) {
            Write-Host "  [清理] 删除不完整的临时文件: $localFile" -ForegroundColor DarkYellow
            Remove-Item $localFile -Force
        }
    } else {
        Write-Host "  [完成]" -ForegroundColor Green
    }
}

# =====================================================================
# 7. 彻底清理临时凭证
# =====================================================================
Write-Host "`n任务结束，正在销毁临时安全凭证..." -ForegroundColor Cyan
Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "脚本执行完毕。" -ForegroundColor White