using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Feedser.Storage.Mongo.Documents;

namespace StellaOps.Feedser.Storage.Mongo.Tests;

[Collection("mongo-fixture")]
public sealed class DocumentStoreTests : IClassFixture<MongoIntegrationFixture>
{
    private readonly MongoIntegrationFixture _fixture;

    public DocumentStoreTests(MongoIntegrationFixture fixture)
    {
        _fixture = fixture;
    }

    [Fact]
    public async Task UpsertAndLookupDocument()
    {
        var store = new DocumentStore(_fixture.Database, NullLogger<DocumentStore>.Instance);
        var id = Guid.NewGuid();
        var record = new DocumentRecord(
            id,
            "source",
            "https://example.com/advisory.json",
            DateTimeOffset.UtcNow,
            "sha123",
            "pending",
            "application/json",
            new Dictionary<string, string> { ["etag"] = "abc" },
            new Dictionary<string, string> { ["note"] = "test" },
            "etag-value",
            DateTimeOffset.UtcNow,
            null,
            DateTimeOffset.UtcNow.AddDays(30));

        var upserted = await store.UpsertAsync(record, CancellationToken.None);
        Assert.Equal(id, upserted.Id);

        var fetched = await store.FindBySourceAndUriAsync("source", "https://example.com/advisory.json", CancellationToken.None);
        Assert.NotNull(fetched);
        Assert.Equal("pending", fetched!.Status);
        Assert.Equal("test", fetched.Metadata!["note"]);

        var statusUpdated = await store.UpdateStatusAsync(id, "processed", CancellationToken.None);
        Assert.True(statusUpdated);

        var refreshed = await store.FindAsync(id, CancellationToken.None);
        Assert.NotNull(refreshed);
        Assert.Equal("processed", refreshed!.Status);
    }
}
