namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;

/// <summary>
///     Append-only audit log for every config write + authorization-check event. Grants revoked for
///     UPDATE / DELETE on all principals (enforced by the authorization migration in B.3).
/// </summary>
public sealed class ConfigAuditLog
{
    /// <summary>Gets or sets the unique audit log identifier.</summary>
    public long AuditId { get; set; }

    /// <summary>Gets or sets the timestamp of the audit event.</summary>
    public DateTime Timestamp { get; set; } = DateTime.UtcNow;

    /// <summary>Gets or sets the principal (user or service) that initiated the event.</summary>
    public required string Principal { get; set; }

    /// <summary>DraftCreated | DraftEdited | Published | RolledBack | NodeApplied | CredentialAdded | CredentialDisabled | ClusterCreated | NodeAdded | ExternalIdReleased | CrossClusterNamespaceAttempt | OpcUaAccessDenied | …</summary>
    public required string EventType { get; set; }

    /// <summary>Gets or sets the cluster identifier associated with the event, if applicable.</summary>
    public string? ClusterId { get; set; }

    /// <summary>Gets or sets the node identifier associated with the event, if applicable.</summary>
    public string? NodeId { get; set; }

    /// <summary>Gets or sets the generation identifier associated with the event, if applicable.</summary>
    public long? GenerationId { get; set; }

    /// <summary>Gets or sets additional event details in JSON format.</summary>
    public string? DetailsJson { get; set; }

    /// <summary>
    /// Stable per-event identifier from <c>AuditEvent.EventId</c>. Filtered unique index on
    /// this column gives cross-restart idempotency for the batched AuditWriterActor: a flush
    /// that retries after a process crash can re-send the same EventId without producing a
    /// duplicate row. Nullable so pre-v2 rows backfill cleanly.
    /// </summary>
    public Guid? EventId { get; set; }

    /// <summary>Correlation ID from <c>AuditEvent.CorrelationId</c> so an audit row joins to its
    /// originating request/workflow. Nullable for the same backfill reason as <see cref="EventId"/>.</summary>
    public Guid? CorrelationId { get; set; }

    /// <summary>Normalized outcome from <c>AuditEvent.Outcome</c> (the canonical
    /// <c>ZB.MOM.WW.Audit.AuditOutcome</c>: <c>Success</c> | <c>Failure</c> | <c>Denied</c>),
    /// stored as its enum member name. Nullable so pre-Outcome rows backfill cleanly and the
    /// bespoke stored-procedure audit path (which does not derive an outcome) writes NULL.</summary>
    public string? Outcome { get; set; }
}
