namespace ZB.MOM.WW.Secrets.Abstractions;

/// <summary>
/// The encrypted, at-rest representation of a secret — one database row. This type
/// <b>never</b> holds plaintext: the secret material lives only in <see cref="Ciphertext"/>,
/// sealed under AES-256-GCM with a per-secret data-encryption key (DEK) that is itself
/// wrapped by the key-encryption key (KEK) identified by <see cref="KekId"/>.
/// </summary>
public record StoredSecret
{
    /// <summary>The normalized secret name (primary identity).</summary>
    public required SecretName Name { get; init; }

    /// <summary>Optional human-readable description shown in management surfaces.</summary>
    public string? Description { get; init; }

    /// <summary>How the decrypted plaintext should be interpreted.</summary>
    public required SecretContentType ContentType { get; init; }

    /// <summary>The AES-256-GCM ciphertext of the secret plaintext.</summary>
    public required byte[] Ciphertext { get; init; }

    /// <summary>The AES-256-GCM nonce used to seal <see cref="Ciphertext"/>.</summary>
    public required byte[] Nonce { get; init; }

    /// <summary>The AES-256-GCM authentication tag for <see cref="Ciphertext"/>.</summary>
    public required byte[] Tag { get; init; }

    /// <summary>The per-secret data-encryption key (DEK), wrapped by the KEK.</summary>
    public required byte[] WrappedDek { get; init; }

    /// <summary>The AES-256-GCM nonce used to wrap <see cref="WrappedDek"/>.</summary>
    public required byte[] WrapNonce { get; init; }

    /// <summary>The AES-256-GCM authentication tag for <see cref="WrappedDek"/>.</summary>
    public required byte[] WrapTag { get; init; }

    /// <summary>Identifier of the key-encryption key (KEK) that wrapped the DEK.</summary>
    public required string KekId { get; init; }

    /// <summary>Monotonic revision number, incremented on each update.</summary>
    public required long Revision { get; init; }

    /// <summary>Whether the secret is soft-deleted (tombstoned).</summary>
    public bool IsDeleted { get; init; }

    /// <summary>When the secret was soft-deleted, if it is deleted; otherwise <c>null</c>.</summary>
    public DateTimeOffset? DeletedUtc { get; init; }

    /// <summary>When the secret was first created (UTC).</summary>
    public required DateTimeOffset CreatedUtc { get; init; }

    /// <summary>When the secret was last updated (UTC).</summary>
    public required DateTimeOffset UpdatedUtc { get; init; }

    /// <summary>Principal that created the secret, if known.</summary>
    public string? CreatedBy { get; init; }

    /// <summary>Principal that last updated the secret, if known.</summary>
    public string? UpdatedBy { get; init; }
}
