# 批量启动边缘节点并在停止时清理所有进程
# 每秒启动100个节点，最多启动10000个

# 存储所有进程ID的数组
$processes = @()
# 计数器
$nodeCounter = 0
# 最大节点数
$maxNodes = 1000
# 每批次启动的节点数
$batchSize = 100
# API地址
$onlineApi = "http://192.168.3.42:8080/api/edge/online"
$offlineApi = "http://192.168.3.42:8080/api/edge/offline"
# 节点可执行文件路径
$edgeExePath = Join-Path -Path $PSScriptRoot -ChildPath "..\bin\proxy_edge_win_amd64.exe"

# 检查可执行文件是否存在
if (-not (Test-Path -Path $edgeExePath)) {
    Write-Host "错误：找不到边缘节点可执行文件: $edgeExePath" -ForegroundColor Red
    Write-Host "请先运行 build-edge.ps1 构建可执行文件" -ForegroundColor Yellow
    exit 1
}

# 定义清理函数，终止所有进程
function Cleanup {
    Write-Host "`n正在终止所有节点进程..." -ForegroundColor Yellow
    
    # 计数器
    $killedCount = 0
    
    foreach ($process in $processes) {
        try {
            $proc = Get-Process -Id $process -ErrorAction SilentlyContinue
            if ($proc) {
                Stop-Process -Id $process -ErrorAction SilentlyContinue
                $killedCount++
                
                # 每终止100个进程显示一次进度
                if ($killedCount % 100 -eq 0) {
                    Write-Host "已终止 $killedCount 个节点进程" -ForegroundColor Cyan
                }
            }
        } catch {
            # 忽略已终止的进程错误
        }
    }
    
    Write-Host "总共终止了 $killedCount 个节点进程" -ForegroundColor Green
    
    # 最后确认清理
    $remainingProcs = Get-Process | Where-Object { $_.Path -eq $edgeExePath }
    if ($remainingProcs) {
        $remainingCount = $remainingProcs.Count
        Write-Host "尝试强制终止剩余的 $remainingCount 个节点进程..." -ForegroundColor Red
        $remainingProcs | Stop-Process -Force -ErrorAction SilentlyContinue
    }
    
    Write-Host "清理完成！" -ForegroundColor Green
}

# 注册Ctrl+C事件处理
$null = [Console]::CancelKeyPress.Connect({
    param($sender, $e)
    $e.Cancel = $true  # 防止立即退出，让清理函数有时间执行
    Cleanup
    exit 0
})

# 显示启动信息
Write-Host "开始批量启动边缘节点..." -ForegroundColor Green
Write-Host "每秒将启动 $batchSize 个节点，最多启动 $maxNodes 个节点" -ForegroundColor Cyan
Write-Host "按下 Ctrl+C 停止并清理所有节点" -ForegroundColor Yellow
Write-Host "--------------------------------------------------" -ForegroundColor White

try {
    while ($nodeCounter -lt $maxNodes) {
        $batchStartTime = Get-Date
        $startedInBatch = 0
        
        # 批量启动节点
        for ($i = 0; $i -lt $batchSize; $i++) {
            # 生成随机名称
            $randomName = "edge-" + [Guid]::NewGuid().ToString().Substring(0, 8)
            
            # 启动进程
            $startInfo = New-Object System.Diagnostics.ProcessStartInfo
            $startInfo.FileName = $edgeExePath
            $startInfo.Arguments = "-n `"$randomName`" -online `"$onlineApi`" -offline `"$offlineApi`""
            $startInfo.UseShellExecute = $false
            $startInfo.CreateNoWindow = $true  # 不显示命令行窗口
            
            $process = [System.Diagnostics.Process]::Start($startInfo)
            $processes += $process.Id
            
            $nodeCounter++
            $startedInBatch++
            
            # 如果达到最大节点数，提前退出循环
            if ($nodeCounter -ge $maxNodes) {
                break
            }
        }
        
        # 计算本批次启动用时
        $batchDuration = (Get-Date) - $batchStartTime
        $batchTimeMs = $batchDuration.TotalMilliseconds
        
        # 显示进度
        Write-Host "已启动 $nodeCounter 个节点 (本批次 $startedInBatch 个，耗时 $([math]::Round($batchTimeMs, 0)) ms)" -ForegroundColor Green
        
        # 计算需要等待的时间以保持每秒启动指定数量节点
        $waitTimeMs = 1000 - $batchTimeMs
        if ($waitTimeMs -gt 0) {
            Start-Sleep -Milliseconds $waitTimeMs
        }
    }
} catch {
    Write-Host "发生错误: $_" -ForegroundColor Red
} finally {
    # 如果达到最大节点数，提示用户
    if ($nodeCounter -ge $maxNodes) {
        Write-Host "`n已达到最大节点数 $maxNodes！" -ForegroundColor Magenta
        Write-Host "按下 Ctrl+C 停止并清理所有节点" -ForegroundColor Yellow
        
        # 保持脚本运行，等待用户手动终止
        try {
            while ($true) { Start-Sleep -Seconds 1 }
        } catch {
            # Ctrl+C被捕获时会进入这里
            Cleanup
        }
    } else {
        # 脚本异常终止时执行清理
        Cleanup
    }
}