// Copyright (c) StellaOps. Licensed under the BUSL-1.1.
using StellaOps.HybridLogicalClock;
using System.Security.Cryptography;
using System.Text;
namespace StellaOps.Eventing.Internal;
///
/// Generates deterministic event IDs from event content.
///
internal static class EventIdGenerator
{
///
/// Generates a deterministic event ID using SHA-256 hash of inputs.
///
/// The correlation ID.
/// The HLC timestamp.
/// The service name.
/// The event kind.
/// First 32 hex characters of SHA-256 hash (128 bits).
public static string Generate(
string correlationId,
HlcTimestamp tHlc,
string service,
string kind)
{
ArgumentException.ThrowIfNullOrWhiteSpace(correlationId);
ArgumentException.ThrowIfNullOrWhiteSpace(service);
ArgumentException.ThrowIfNullOrWhiteSpace(kind);
using var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256);
// Append all inputs in deterministic order
hasher.AppendData(Encoding.UTF8.GetBytes(correlationId));
hasher.AppendData(Encoding.UTF8.GetBytes(tHlc.ToSortableString()));
hasher.AppendData(Encoding.UTF8.GetBytes(service));
hasher.AppendData(Encoding.UTF8.GetBytes(kind));
var hash = hasher.GetHashAndReset();
// Return first 16 bytes (128 bits) as lowercase hex (32 chars)
return Convert.ToHexString(hash.AsSpan(0, 16)).ToLowerInvariant();
}
///
/// Computes SHA-256 digest of the payload.
///
/// The canonicalized JSON payload.
/// SHA-256 digest bytes.
public static byte[] ComputePayloadDigest(string payload)
{
ArgumentNullException.ThrowIfNull(payload);
return SHA256.HashData(Encoding.UTF8.GetBytes(payload));
}
}