using System;
using System.Linq;
using System.Threading;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using StellaOps.Feedser.Storage.Mongo;
using StellaOps.Feedser.Storage.Mongo.Migrations;
using Xunit;

namespace StellaOps.Feedser.Storage.Mongo.Tests;

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

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

    [Fact]
    public async Task InitializeAsync_CreatesNormalizedIndexesWhenSemVerStyleEnabled()
    {
        var databaseName = $"feedser-bootstrap-semver-{Guid.NewGuid():N}";
        var database = _fixture.Client.GetDatabase(databaseName);

        try
        {
            var runner = new MongoMigrationRunner(
                database,
                Array.Empty<IMongoMigration>(),
                NullLogger<MongoMigrationRunner>.Instance,
                TimeProvider.System);

            var bootstrapper = new MongoBootstrapper(
                database,
                Options.Create(new MongoStorageOptions { EnableSemVerStyle = true }),
                NullLogger<MongoBootstrapper>.Instance,
                runner);

            await bootstrapper.InitializeAsync(CancellationToken.None);

            var indexCursor = await database
                .GetCollection<BsonDocument>(MongoStorageDefaults.Collections.Advisory)
                .Indexes
                .ListAsync();
            var indexNames = (await indexCursor.ToListAsync()).Select(x => x["name"].AsString).ToArray();

            Assert.Contains("advisory_normalizedVersions_pkg_scheme_type", indexNames);
            Assert.Contains("advisory_normalizedVersions_value", indexNames);
        }
        finally
        {
            await _fixture.Client.DropDatabaseAsync(databaseName);
        }
    }

    [Fact]
    public async Task InitializeAsync_DoesNotCreateNormalizedIndexesWhenFeatureDisabled()
    {
        var databaseName = $"feedser-bootstrap-no-semver-{Guid.NewGuid():N}";
        var database = _fixture.Client.GetDatabase(databaseName);

        try
        {
            var runner = new MongoMigrationRunner(
                database,
                Array.Empty<IMongoMigration>(),
                NullLogger<MongoMigrationRunner>.Instance,
                TimeProvider.System);

            var bootstrapper = new MongoBootstrapper(
                database,
                Options.Create(new MongoStorageOptions { EnableSemVerStyle = false }),
                NullLogger<MongoBootstrapper>.Instance,
                runner);

            await bootstrapper.InitializeAsync(CancellationToken.None);

            var indexCursor = await database
                .GetCollection<BsonDocument>(MongoStorageDefaults.Collections.Advisory)
                .Indexes
                .ListAsync();
            var indexNames = (await indexCursor.ToListAsync()).Select(x => x["name"].AsString).ToArray();

            Assert.DoesNotContain("advisory_normalizedVersions_pkg_scheme_type", indexNames);
            Assert.DoesNotContain("advisory_normalizedVersions_value", indexNames);
        }
        finally
        {
            await _fixture.Client.DropDatabaseAsync(databaseName);
        }
    }
}
