using DragonISO.Engine.Domain;

namespace DragonISO.Engine.Pipeline;

/// <summary>
/// Per-pipeline configuration â€” identifies the participant, the source it captures,
/// the output it emits, and the global processing settings to apply.
/// </summary>
public sealed record IsoPipelineConfig(
    Guid ParticipantId,
    string SourceName,
    string OutputName,
    FrameProcessingSettings Settings)
{
    /// <summary>Default no-signal threshold per spec Â§4.</summary>
    public TimeSpan SlateThreshold { get; init; } = TimeSpan.FromSeconds(2.5);

    /// <summary>Bounded raw-frame channel capacity (drop-oldest backpressure).</summary>
    public int RawChannelCapacity { get; init; } = 4;

    /// <summary>Bounded processed-frame channel capacity.</summary>
    public int ProcessedChannelCapacity { get; init; } = 2;

    /// <summary>
    /// NDI groups (comma-separated) the output sender broadcasts on. <c>null</c> means
    /// "use the NDI default" (Public). Set per pipeline so the controller can drive it
    /// from the global NdiGroupSettings without changing this record's identity contract.
    /// </summary>
    public string? OutputGroups { get; init; }

    /// <summary>
    /// Optional recorder. When non-null, every <see cref="ProcessedFrame"/> emitted by
    /// the inner pipeline is also fed to this sink for persistence. The pipeline owns
    /// the recorder's lifecycle: <see cref="IRecorderSink.Open"/> on the first frame
    /// (so we know the actual output dimensions), <see cref="IRecorderSink.Close"/>
    /// when the inner loop ends or the supervisor cancels.
    /// </summary>
    public IRecorderSink? Recorder { get; init; }

    /// <summary>
    /// Output directory for the recorder, if one is configured. The recorder will
    /// create a subdirectory named after the participant under this root. Ignored
    /// when <see cref="Recorder"/> is null.
    /// </summary>
    public string? RecordingOutputDirectory { get; init; }

    /// <summary>
    /// Operator-facing display name; used by the recorder to derive the filename.
    /// Distinct from <see cref="OutputName"/> (the NDI source name, which is for
    /// machine consumption) â€” the recorder wants something human-readable.
    /// </summary>
    public string? RecorderDisplayName { get; init; }
}
