using System.Text; namespace Sonex.Worker.DatabaseBackup; internal sealed class DatabaseBackupRunReport { private readonly List _copyResults = []; public DateTime StartedAtUtc { get; } = DateTime.UtcNow; public string BackupDirectoryPath { get; set; } = string.Empty; public string BackupLogFilePath { get; set; } = string.Empty; public long BackupSizeBytes { get; set; } public bool BackupSucceeded { get; set; } public void RegisterCopyResult(string targetPath, bool success, string details) { _copyResults.Add(new CopyResult { TargetPath = targetPath, Success = success, Details = details }); } public string BuildSummary(TimeSpan duration) { int successfulCopies = _copyResults.Count(static item => item.Success); int failedCopies = _copyResults.Count - successfulCopies; return $"Worker finished. Duration: {duration:hh\\:mm\\:ss}. " + $"BackupSuccess={BackupSucceeded}. BackupSize={FormatBytes(BackupSizeBytes)}. " + $"CopySuccess={successfulCopies}. CopyFailed={failedCopies}."; } public string BuildFullReport(TimeSpan duration) { var sb = new StringBuilder(); sb.AppendLine(BuildSummary(duration)); sb.AppendLine($"Backup directory: {BackupDirectoryPath}"); sb.AppendLine($"Backup log file: {BackupLogFilePath}"); if (_copyResults.Count == 0) { sb.AppendLine("Copy targets: none"); return sb.ToString().TrimEnd(); } sb.AppendLine("Copy targets:"); foreach (CopyResult copyResult in _copyResults) { sb.AppendLine( $"- Success={copyResult.Success}; Target={copyResult.TargetPath}; Details={copyResult.Details}"); } return sb.ToString().TrimEnd(); } private static string FormatBytes(long bytes) { if (bytes <= 0) return "0 B"; string[] units = ["B", "KB", "MB", "GB", "TB"]; double value = bytes; int index = 0; while (value >= 1024 && index < units.Length - 1) { value /= 1024; index++; } return $"{value:F2} {units[index]}"; } private sealed class CopyResult { public string TargetPath { get; init; } = string.Empty; public bool Success { get; init; } public string Details { get; init; } = string.Empty; } }