using System.Collections.Concurrent;
using ZB.MOM.WW.Secrets.Abstractions;

namespace ZB.MOM.WW.Secrets.Tests.Fakes;

/// <summary>
/// An in-memory <see cref="ISecretStore"/> test double that counts <see cref="GetAsync"/> calls so
/// a test can prove a resolver cache hit (or miss). Only the read path exercised by
/// <c>DefaultSecretResolver</c> is meaningfully implemented; the mutation / replication members
/// throw so an accidental dependency on them fails loudly rather than silently no-ops.
/// </summary>
public sealed class CountingSecretStore : ISecretStore
{
    private readonly ConcurrentDictionary<string, StoredSecret> _rows = new(StringComparer.Ordinal);
    private int _getCount;

    /// <summary>The number of times <see cref="GetAsync"/> has been invoked.</summary>
    public int GetCount => Volatile.Read(ref _getCount);

    /// <summary>Seeds (or overwrites) a row keyed by its normalized name.</summary>
    /// <param name="row">The encrypted row to seed.</param>
    public void Seed(StoredSecret row) => _rows[row.Name.Value] = row;

    /// <inheritdoc />
    public Task<StoredSecret?> GetAsync(SecretName name, CancellationToken ct)
    {
        Interlocked.Increment(ref _getCount);
        _rows.TryGetValue(name.Value, out StoredSecret? row);
        return Task.FromResult(row);
    }

    /// <inheritdoc />
    public Task UpsertAsync(StoredSecret row, CancellationToken ct) =>
        throw new NotSupportedException();

    /// <inheritdoc />
    public Task<bool> DeleteAsync(SecretName name, string? actor, CancellationToken ct) =>
        throw new NotSupportedException();

    /// <inheritdoc />
    public Task<IReadOnlyList<SecretMetadata>> ListAsync(bool includeDeleted, CancellationToken ct) =>
        throw new NotSupportedException();

    /// <inheritdoc />
    public Task<IReadOnlyList<SecretManifestEntry>> GetManifestAsync(CancellationToken ct) =>
        throw new NotSupportedException();

    /// <inheritdoc />
    public Task ApplyReplicatedAsync(StoredSecret row, CancellationToken ct) =>
        throw new NotSupportedException();

    /// <inheritdoc />
    public Task<bool> ApplyRewrapAsync(
        StoredSecret rewrappedRow, byte[] expectedCurrentWrappedDek, CancellationToken ct) =>
        throw new NotSupportedException();
}
