using System.Collections.Concurrent;
using StellaOps.Scanner.Storage.ObjectStore;

namespace StellaOps.Scanner.Storage.Tests;

internal sealed class InMemoryArtifactObjectStore : IArtifactObjectStore
{
    private readonly ConcurrentDictionary<(string Bucket, string Key), byte[]> _objects = new();

    public IReadOnlyDictionary<(string Bucket, string Key), byte[]> Objects => _objects;

    public Task DeleteAsync(ArtifactObjectDescriptor descriptor, CancellationToken cancellationToken)
    {
        _objects.TryRemove((descriptor.Bucket, descriptor.Key), out _);
        return Task.CompletedTask;
    }

    public Task<Stream?> GetAsync(ArtifactObjectDescriptor descriptor, CancellationToken cancellationToken)
    {
        if (_objects.TryGetValue((descriptor.Bucket, descriptor.Key), out var bytes))
        {
            return Task.FromResult<Stream?>(new MemoryStream(bytes, writable: false));
        }

        return Task.FromResult<Stream?>(null);
    }

    public async Task PutAsync(ArtifactObjectDescriptor descriptor, Stream content, CancellationToken cancellationToken)
    {
        using var buffer = new MemoryStream();
        await content.CopyToAsync(buffer, cancellationToken).ConfigureAwait(false);
        _objects[(descriptor.Bucket, descriptor.Key)] = buffer.ToArray();
    }
}
