rainbow-dragon/Sources/ForgeOffload/OffloadReportWriter.swift

50 lines
1.8 KiB
Swift

import Foundation
/// Offload report renderers: CSV (machine) + HTML (producer handoff).
public enum OffloadReportWriter {
public static func csv(_ report: OffloadReport) -> String {
var out = "relative_path,size,xxh64,verified,skipped\n"
for f in report.files {
out += "\(f.relativePath),\(f.size),\(f.xxh64),\(f.verified),\(f.skipped)\n"
}
return out
}
public static func formatBytes(_ bytes: UInt64) -> String {
let mb = Double(bytes) / 1_000_000
if mb >= 1000 {
return String(format: "%.2f GB", mb / 1000)
}
return String(format: "%.1f MB", mb)
}
public static func html(_ report: OffloadReport) -> String {
let allVerified = report.files.allSatisfy(\.verified)
var rows = ""
for f in report.files {
rows += """
<tr><td>\(f.relativePath)</td><td>\(formatBytes(f.size))</td>\
<td><code>\(f.xxh64)</code></td>\
<td>\(f.verified ? "OK" : "FAIL")</td>\
<td>\(f.skipped ? "skipped" : "copied")</td></tr>\n
"""
}
return """
<html>
<head><title>Forge Offload Report</title>
<style>body{font-family:sans-serif}table{border-collapse:collapse}td,th{border:1px solid #ccc;padding:4px 8px}</style>
</head>
<body>
<h1>Offload Report — \(allVerified ? "VERIFIED" : "FAILURES PRESENT")</h1>
<p>Source: \(report.source)</p>
<p>Destinations: \(report.destinations.joined(separator: ", "))</p>
<p>\(report.files.count) files, \(formatBytes(report.totalBytes)), \(String(format: "%.1f", report.duration))s</p>
<table>
<tr><th>File</th><th>Size</th><th>xxHash64</th><th>Verify</th><th>Action</th></tr>
\(rows)</table>
</body>
</html>
"""
}
}