import Foundation
import ForgeColor
import ForgeGrade
import ForgeLibrary
/// Producer/post-facing HTML shot report — Reel design tokens, still thumbnails
/// (base64-embedded so the file is self-contained/mailable), grade + metadata per shot.
public enum ShotReport {
static func escapeHTML(_ s: String) -> String {
s.replacingOccurrences(of: "&", with: "&")
.replacingOccurrences(of: "<", with: "<")
.replacingOccurrences(of: ">", with: ">")
}
static func f3(_ v: Float) -> String {
String(format: "%.3f", v)
}
static func cdl(from shot: Shot) -> CDL? {
guard let data = shot.gradeSnapshot,
let stack = try? GradeSnapshot.decode(data) else { return nil }
for node in stack.nodes {
if case .cdl(let c) = node.kind, node.isEnabled { return c }
}
return nil
}
static func stillDataURI(_ shot: Shot) -> String? {
guard let path = shot.stillPath,
let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else { return nil }
let mime = path.hasSuffix(".png") ? "image/png" : "image/x-portable-pixmap"
return "data:\(mime);base64,\(data.base64EncodedString())"
}
public static func html(shots: [Shot], projectName: String, dayLabel: String, date: String) -> String {
var rows = ""
for s in shots {
let c = cdl(from: s)
let still: String
if let uri = stillDataURI(s) {
still = ""
} else {
still = "