using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;

namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;

/// <summary>
/// Filter predicate for <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories.IAuditLogRepository.QueryAsync"/>.
/// Any field left <c>null</c> means "do not constrain on that column". The
/// <see cref="Channels"/>, <see cref="Kinds"/>, <see cref="Statuses"/>,
/// <see cref="SourceSiteIds"/> and <see cref="SourceNodes"/> dimensions are
/// multi-value: a <c>null</c> OR empty list means "do not constrain", and a
/// non-empty list is OR-combined within the dimension (translated to a SQL
/// <c>IN (…)</c>). Time bounds are half-open in the spec sense —
/// <see cref="FromUtc"/> is inclusive and <see cref="ToUtc"/> is inclusive of
/// the upper bound; the repository SQL uses <c>&gt;=</c> / <c>&lt;=</c>
/// respectively. All filter dimensions are AND-combined with one another. The
/// single-value <see cref="CorrelationId"/>, <see cref="ExecutionId"/> and
/// <see cref="ParentExecutionId"/> dimensions constrain on equality when set.
/// </summary>
/// <param name="SourceNodes">
/// Restrict to rows whose <c>SourceNode</c> matches one of the supplied node
/// identifiers (e.g. <c>"central-a"</c>, <c>"site-plant-a-node-a"</c>). A null
/// or empty list means "do not constrain"; a non-empty list is translated to
/// SQL <c>SourceNode IN (…)</c>. Rows with NULL <c>SourceNode</c> are excluded
/// when the filter is set (the same SourceSiteIds contract).
/// </param>
public sealed record AuditLogQueryFilter(
    IReadOnlyList<AuditChannel>? Channels = null,
    IReadOnlyList<AuditKind>? Kinds = null,
    IReadOnlyList<AuditStatus>? Statuses = null,
    IReadOnlyList<string>? SourceSiteIds = null,
    string? Target = null,
    string? Actor = null,
    Guid? CorrelationId = null,
    Guid? ExecutionId = null,
    Guid? ParentExecutionId = null,
    DateTime? FromUtc = null,
    DateTime? ToUtc = null,
    IReadOnlyList<string>? SourceNodes = null);
