# 完全兼容你的环境
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

# 配置项
$JobName = "veeam_backup"
$InstanceName = $env:COMPUTERNAME
$OutputFile = Join-Path -Path $PWD.Path -ChildPath "veeam_metrics.prom"

# Linux 上传配置
$linuxUser = "root"
$linuxIP   = "10.150.117.190"
$linuxPath = "/opt/prom_textfile/"
$localFile = ".\veeam_metrics.prom"

while ($true) {
    $Metrics = @()
    $TodayStart = (Get-Date).Date
    $GlobalTotalJobs = 0
    $GlobalSuccessJobs = 0
    $GlobalFailedJobs = 0
    $GlobalRunningJobs = 0
    $GlobalDailyTotalBackup = 0

    # ================== 指标头部 ==================
    $Metrics += "# HELP veeam_job_status Veeam backup job status (0=Success,1=Warning,2=Failed,3=None)"
    $Metrics += "# TYPE veeam_job_status gauge"
    $Metrics += "# HELP veeam_job_is_running Veeam job is running (1=running,0=idle)"
    $Metrics += "# TYPE veeam_job_is_running gauge"
    $Metrics += "# HELP veeam_job_progress_percent Veeam job progress percentage"
    $Metrics += "# TYPE veeam_job_progress_percent gauge"
    $Metrics += "# HELP veeam_job_backup_size_gb Veeam last backup size in GB"
    $Metrics += "# TYPE veeam_job_backup_size_gb gauge"
    $Metrics += "# HELP veeam_job_data_size_gb Veeam last processed data size in GB"
    $Metrics += "# TYPE veeam_job_data_size_gb gauge"
    $Metrics += "# HELP veeam_job_duration_seconds Veeam last job duration in seconds"
    $Metrics += "# TYPE veeam_job_duration_seconds gauge"
    $Metrics += "# HELP veeam_job_daily_backup_size_gb Veeam job total backup size today in GB"
    $Metrics += "# TYPE veeam_job_daily_backup_size_gb gauge"
    $Metrics += "# HELP veeam_repo_free_space_gb Veeam repository free space in GB"
    $Metrics += "# TYPE veeam_repo_free_space_gb gauge"
    $Metrics += "# HELP veeam_repo_total_space_gb Veeam repository total space in GB"
    $Metrics += "# TYPE veeam_repo_total_space_gb gauge"

    # 全局统计指标
    $Metrics += "# HELP veeam_global_total_jobs Total number of Veeam backup jobs"
    $Metrics += "# TYPE veeam_global_total_jobs gauge"
    $Metrics += "# HELP veeam_global_success_jobs Number of successful Veeam backup jobs"
    $Metrics += "# TYPE veeam_global_success_jobs gauge"
    $Metrics += "# HELP veeam_global_failed_jobs Number of failed Veeam backup jobs"
    $Metrics += "# TYPE veeam_global_failed_jobs gauge"
    $Metrics += "# HELP veeam_global_running_jobs Number of running Veeam backup jobs"
    $Metrics += "# TYPE veeam_global_running_jobs gauge"
    $Metrics += "# HELP veeam_global_daily_total_gb Total backup size of all jobs today in GB"
    $Metrics += "# TYPE veeam_global_daily_total_gb gauge"
    $Metrics += "# HELP veeam_global_success_rate Overall backup success rate today (0-100)"
    $Metrics += "# TYPE veeam_global_success_rate gauge"

    # 单任务健康度指标
    $Metrics += "# HELP veeam_job_last_success_timestamp Last successful backup timestamp (Unix seconds)"
    $Metrics += "# TYPE veeam_job_last_success_timestamp gauge"
    $Metrics += "# HELP veeam_job_since_last_success_hours Hours since last successful backup"
    $Metrics += "# TYPE veeam_job_since_last_success_hours gauge"
    $Metrics += "# HELP veeam_job_compression_ratio Backup compression ratio (data_size/backup_size)"
    $Metrics += "# TYPE veeam_job_compression_ratio gauge"

    # 存储智能预警指标
    $Metrics += "# HELP veeam_repo_usage_percent Repository usage percentage (0-100)"
    $Metrics += "# TYPE veeam_repo_usage_percent gauge"
    $Metrics += "# HELP veeam_repo_remaining_days Estimated remaining days based on daily backup rate"
    $Metrics += "# TYPE veeam_repo_remaining_days gauge"
    $Metrics += ""

    # ================== 1. 备份任务指标 ==================
    $Jobs = Get-VBRJob | Where-Object { $_.JobType -eq "Backup" }
    $GlobalTotalJobs = $Jobs.Count
    $AllSessions = Get-VBRBackupSession
    $Now = Get-Date  # 提前获取当前时间，避免循环中多次调用

    foreach ($Job in $Jobs) {
        $LastSession = $Job.FindLastSession()
        $Status = if ($LastSession) { $LastSession.Result } else { "None" }
        $State = if ($LastSession) { $LastSession.State } else { "Idle" }
        
        $StatusCode = switch ($Status) {
            "Success" { 0; $GlobalSuccessJobs++ }
            "Warning" { 1; $GlobalSuccessJobs++ }
            "Failed"  { 2; $GlobalFailedJobs++ }
            default   { 3 }
        }
        
        $IsRunning = if ($State -eq "Working") { 1; $GlobalRunningJobs++ } else { 0 }
        $CleanJobName = $Job.Name -replace '[^a-zA-Z0-9_]', '_' -replace '[\r\n`"''"]', ''

        # 基础指标
        $Metrics += "veeam_job_status{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $StatusCode"
        $Metrics += "veeam_job_is_running{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $IsRunning"
        $Metrics += "veeam_job_progress_percent{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $(if($LastSession-and$State-eq'Working'){$LastSession.Progress.Percents}else{0})"

        # 备份大小和数据量（兼容所有版本）
        if ($LastSession) {
            if ($State -eq "Working") {
                $BackupSizeGB = if ($LastSession.Info.Progress.BackupSize) { [math]::Round($LastSession.Info.Progress.BackupSize / 1GB, 2) } else { 0 }
                $DataSizeGB = if ($LastSession.Info.Progress.DataSize) { [math]::Round($LastSession.Info.Progress.DataSize / 1GB, 2) } else { 0 }
            } else {
                $BackupSizeGB = if ($LastSession.BackupStats.BackupSize) { [math]::Round($LastSession.BackupStats.BackupSize / 1GB, 2) } else { 0 }
                $DataSizeGB = if ($LastSession.BackupStats.DataSize) { [math]::Round($LastSession.BackupStats.DataSize / 1GB, 2) } else { 0 }
            }
            $DurationSeconds = if ($LastSession.EndTime -and $LastSession.CreationTime) { [math]::Round(($LastSession.EndTime - $LastSession.CreationTime).TotalSeconds, 2) } else { 0 }
        } else {
            $BackupSizeGB = 0
            $DataSizeGB = 0
            $DurationSeconds = 0
        }
        $Metrics += "veeam_job_backup_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $BackupSizeGB"
        $Metrics += "veeam_job_data_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DataSizeGB"
        $Metrics += "veeam_job_duration_seconds{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DurationSeconds"

        # 当日备份量
        $TodaySessions = $AllSessions | Where-Object { $_.JobId -eq $Job.Id -and $_.CreationTime -ge $TodayStart }
        $DailyBackupSizeGB = 0
        foreach ($Session in $TodaySessions) {
            if ($Session.BackupStats.BackupSize) {
                $DailyBackupSizeGB += $Session.BackupStats.BackupSize / 1GB
            }
        }
        $DailyBackupSizeGB = [math]::Round($DailyBackupSizeGB, 2)
        $GlobalDailyTotalBackup += $DailyBackupSizeGB
        $Metrics += "veeam_job_daily_backup_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DailyBackupSizeGB"

        # ✅ 修复：日期计算语法错误（用括号强制优先级）
        $JobSuccessSessions = $AllSessions | Where-Object { $_.JobId -eq $Job.Id -and $_.Result -eq "Success" } | Sort-Object EndTime -Descending
        $LastSuccessSession = $JobSuccessSessions | Select-Object -First 1
        
        if ($LastSuccessSession -and $LastSuccessSession.EndTime) {
            $LastSuccessTimestamp = [math]::Round($LastSuccessSession.EndTime.ToUniversalTime().Subtract((Get-Date "1970-01-01")).TotalSeconds, 0)
            # 关键修复：用括号把 Get-Date 括起来，避免语法解析错误
            $TimeDiff = ($Now) - $LastSuccessSession.EndTime
            $SinceLastSuccessHours = [math]::Round($TimeDiff.TotalHours, 1)
        } else {
            $LastSuccessTimestamp = 0
            $SinceLastSuccessHours = 9999
        }
        $Metrics += "veeam_job_last_success_timestamp{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $LastSuccessTimestamp"
        $Metrics += "veeam_job_since_last_success_hours{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $SinceLastSuccessHours"
        
        # 压缩率
        $CompressionRatio = if ($BackupSizeGB -gt 0) { [math]::Round($DataSizeGB / $BackupSizeGB, 2) } else { 0 }
        $Metrics += "veeam_job_compression_ratio{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $CompressionRatio"
    }

    # 全局统计
    $GlobalSuccessRate = if ($GlobalTotalJobs -gt 0) { [math]::Round(($GlobalSuccessJobs / $GlobalTotalJobs) * 100, 1) } else { 0 }
    $Metrics += "veeam_global_total_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalTotalJobs"
    $Metrics += "veeam_global_success_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalSuccessJobs"
    $Metrics += "veeam_global_failed_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalFailedJobs"
    $Metrics += "veeam_global_running_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalRunningJobs"
    $Metrics += "veeam_global_daily_total_gb{job=`"$JobName`",instance=`"$InstanceName`"} $([math]::Round($GlobalDailyTotalBackup, 2))"
    $Metrics += "veeam_global_success_rate{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalSuccessRate"
    $Metrics += ""

    # ================== 2. 存储库指标 ==================
    $Repositories = Get-VBRBackupRepository
    foreach ($Repo in $Repositories) {
        $Path = $Repo.Path
        $DriveLetter = (Split-Path $Path -Qualifier).TrimEnd(':')
        $DiskInfo = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$DriveLetter`:'" -ErrorAction SilentlyContinue
        
        $FreeSpaceGB = if ($DiskInfo -and $DiskInfo.FreeSpace) { [math]::Round($DiskInfo.FreeSpace / 1GB, 2) } else { 0 }
        $TotalSpaceGB = if ($DiskInfo -and $DiskInfo.Size) { [math]::Round($DiskInfo.Size / 1GB, 2) } else { 0 }
        $CleanRepoName = $Repo.Name -replace '[^a-zA-Z0-9_]', '_' -replace '[\r\n`"''"]', ''

        $Metrics += "veeam_repo_free_space_gb{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $FreeSpaceGB"
        $Metrics += "veeam_repo_total_space_gb{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $TotalSpaceGB"

        # 存储使用率和剩余天数
        $UsagePercent = if ($TotalSpaceGB -gt 0) { [math]::Round((($TotalSpaceGB - $FreeSpaceGB) / $TotalSpaceGB) * 100, 1) } else { 0 }
        $Metrics += "veeam_repo_usage_percent{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $UsagePercent"
        
        $RemainingDays = if ($GlobalDailyTotalBackup -gt 0 -and $FreeSpaceGB -gt 0) { [math]::Round($FreeSpaceGB / $GlobalDailyTotalBackup, 1) } else { 999 }
        $Metrics += "veeam_repo_remaining_days{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $RemainingDays"
    }

    # ================== 格式保证 & 上传 ==================
    $Metrics += ""
    $MetricsBody = $Metrics -join "`n" -replace "`r", ""
    [System.IO.File]::WriteAllText($OutputFile, $MetricsBody, [System.Text.UTF8Encoding]::new($false))

    Write-Host "`n📤 正在上传指标文件..." -ForegroundColor Cyan
    scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL $localFile "${linuxUser}@${linuxIP}:${linuxPath}"
    if ($LASTEXITCODE -eq 0) {
        ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL "${linuxUser}@${linuxIP}" "sed -i 's/\r$//;s/[^[:print:]]//g' ${linuxPath}veeam_metrics.prom && chmod 644 ${linuxPath}veeam_metrics.prom"
        Write-Host "✅ [$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] 采集完成"
        Write-Host "   - 总任务: $GlobalTotalJobs | 成功: $GlobalSuccessJobs | 失败: $GlobalFailedJobs | 运行中: $GlobalRunningJobs"
        Write-Host "   - 今日总备份: $([math]::Round($GlobalDailyTotalBackup, 2)) GB | 成功率: $GlobalSuccessRate%"
        Write-Host "   - 无任何语法错误，等待60秒`n" -ForegroundColor Green
    } else {
        Write-Host "❌ 上传失败，请检查SSH免密配置" -ForegroundColor Red
    }

    Start-Sleep -Seconds 60
}