namespace DeepDrftContent.Processors;
///
/// The product of processing an uploaded audio file on the store path: the metadata SQL and the
/// vault index need, plus a streamed writer that emits the canonical vault bytes to a destination
/// stream without ever materializing the whole file in a managed byte[].
///
/// This replaces the former whole-file AudioBinary as the processor output for upload /
/// replace-audio (Wave 1 OOM fix): passthrough formats (standard-PCM WAV, MP3, FLAC) stream the
/// source file straight to the destination, and EXTENSIBLE WAVs stream their normalization to
/// standard PCM. The vault load path still uses AudioBinary (a full buffer) — that
/// is the Wave 2 read path and is out of scope here.
///
/// is invoked exactly once by the streaming vault register, against the
/// freshly opened backing . The writer re-opens the source file
/// itself, so the source (a staging file) must still exist when the register runs — it does, because
/// processing and registration are sequential within the store call, before the staging-file
/// finally cleanup.
///
public sealed class ProcessedAudio
{
/// The stored file extension (e.g. .wav, .mp3, .flac).
public string Extension { get; }
/// Audio duration in seconds, extracted from the header.
public double Duration { get; }
/// Audio bitrate in kbps, extracted from (or estimated for) the header.
public int Bitrate { get; }
///
/// The canonical stored byte count — computed from the header and file length, never by
/// buffering the body. Used only for diagnostics (confirming the streamed path was taken).
///
public long Size { get; }
private readonly Func _writeTo;
public ProcessedAudio(
string extension,
double duration,
int bitrate,
long size,
Func writeTo)
{
Extension = extension;
Duration = duration;
Bitrate = bitrate;
Size = size;
_writeTo = writeTo;
}
///
/// Streams the canonical vault bytes to . Bounded-buffer — peak
/// managed memory is O(buffer), not O(filesize).
///
public Task WriteToAsync(Stream destination, CancellationToken cancellationToken = default)
=> _writeTo(destination, cancellationToken);
///
/// Builds a passthrough plan: the stored bytes are byte-identical to the source file (standard
/// PCM WAV, MP3, FLAC — no transcoding). The writer is a bounded disk-to-disk copy.
///
public static ProcessedAudio Passthrough(
string sourcePath, string extension, double duration, int bitrate, long sourceLength)
=> new(extension, duration, bitrate, sourceLength,
(destination, ct) => AudioStoreStream.CopyFileAsync(sourcePath, destination, ct));
}