namespace ZB.MOM.WW.Secrets.Abstractions;

/// <summary>
/// Envelope-encrypts and decrypts secret material. Each secret is sealed under a per-secret
/// data-encryption key (DEK) that is itself wrapped by the master key (KEK) from an
/// <see cref="IMasterKeyProvider"/>. The secret name is bound as additional authenticated
/// data (AAD) so ciphertext cannot be silently relocated to a different name.
/// </summary>
public interface ISecretCipher
{
    /// <summary>
    /// Envelope-encrypts <paramref name="plaintext"/>, binding it to <paramref name="name"/>
    /// as additional authenticated data.
    /// </summary>
    /// <param name="name">The secret name, bound as AAD.</param>
    /// <param name="plaintext">The secret plaintext to seal.</param>
    /// <param name="contentType">How the plaintext should be interpreted by consumers.</param>
    /// <returns>
    /// A <see cref="StoredSecret"/> carrying the ciphertext, nonce, tag, and wrapped DEK, with
    /// <see cref="StoredSecret.Revision"/> 0 and default timestamps — the store stamps the
    /// revision and timestamps on persist.
    /// </returns>
    StoredSecret Encrypt(SecretName name, string plaintext, SecretContentType contentType);

    /// <summary>
    /// Decrypts the value carried by a stored row, verifying its authentication tag and the
    /// name it was bound to.
    /// </summary>
    /// <param name="secret">The stored row to decrypt.</param>
    /// <returns>The decrypted plaintext.</returns>
    /// <exception cref="SecretDecryptionException">
    /// The authentication tag fails to verify, or the row references an unknown or unavailable KEK.
    /// </exception>
    string Decrypt(StoredSecret secret);
}
