using Akka.Actor;
using ZB.MOM.WW.Secrets.Abstractions;

namespace ZB.MOM.WW.Secrets.Replicator.AkkaDotNet;

/// <summary>
/// Publishes local secret writes to cluster peers by handing them to this node's
/// <see cref="SecretReplicationActor"/>.
/// </summary>
/// <remarks>
/// The hand-off is a <c>Tell</c>, so <see cref="PublishAsync"/> completes as soon as the row is in
/// the actor's mailbox rather than when peers have applied it. That is the correct contract here:
/// the caller (<c>ReplicatingSecretStore</c>) has already durably written the row locally and treats
/// publishing as best-effort, and blocking a write until every peer acknowledged would make each
/// node's availability depend on all the others. Delivery is guaranteed by anti-entropy, not by
/// this call.
/// </remarks>
/// <param name="replicationActor">This node's replication actor.</param>
public sealed class AkkaSecretReplicator(IActorRef replicationActor) : ISecretReplicator
{
    private readonly IActorRef _replicationActor =
        replicationActor ?? throw new ArgumentNullException(nameof(replicationActor));

    /// <inheritdoc />
    public Task PublishAsync(StoredSecret row, CancellationToken ct)
    {
        ArgumentNullException.ThrowIfNull(row);

        _replicationActor.Tell(new SecretReplicationActor.PublishLocalWrite(row));

        return Task.CompletedTask;
    }
}
