using Amazon.S3;
using Amazon.S3.Model;
using Moq;
using StellaOps.Vexer.ArtifactStores.S3;
using StellaOps.Vexer.Export;

namespace StellaOps.Vexer.ArtifactStores.S3.Tests;

public sealed class S3ArtifactClientTests
{
    [Fact]
    public async Task ObjectExistsAsync_ReturnsTrue_WhenMetadataSucceeds()
    {
        var mock = new Mock<IAmazonS3>();
        mock.Setup(x => x.GetObjectMetadataAsync("bucket", "key", default)).ReturnsAsync(new GetObjectMetadataResponse
        {
            HttpStatusCode = System.Net.HttpStatusCode.OK,
        });

        var client = new S3ArtifactClient(mock.Object, Microsoft.Extensions.Logging.Abstractions.NullLogger<S3ArtifactClient>.Instance);
        var exists = await client.ObjectExistsAsync("bucket", "key", default);
        Assert.True(exists);
    }

    [Fact]
    public async Task PutObjectAsync_MapsMetadata()
    {
        var mock = new Mock<IAmazonS3>();
        mock.Setup(x => x.PutObjectAsync(It.IsAny<PutObjectRequest>(), default))
            .ReturnsAsync(new PutObjectResponse());

        var client = new S3ArtifactClient(mock.Object, Microsoft.Extensions.Logging.Abstractions.NullLogger<S3ArtifactClient>.Instance);
        using var stream = new MemoryStream(new byte[] { 1, 2, 3 });
        await client.PutObjectAsync("bucket", "key", stream, new Dictionary<string, string> { ["a"] = "b" }, default);

        mock.Verify(x => x.PutObjectAsync(It.Is<PutObjectRequest>(r => r.Metadata["a"] == "b"), default), Times.Once);
    }
}
