using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using DD.Persistence.Client;
using DD.Persistence.Database.Model;
using DD.Persistence.App;
using DD.Persistence.Database.Postgres.Extensions;

namespace DD.Persistence.IntegrationTests;
public class WebAppFactoryFixture : WebApplicationFactory<Program>
{
    private string connectionString = string.Empty;

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile("appsettings.Tests.json");
            var configurationRoot = config.Build();
            var dbConnection = configurationRoot.GetSection("DbConnection").Get<DbConnection>()!;
            connectionString = dbConnection.GetConnectionString();
        });

        builder.ConfigureServices(services =>
        {
            var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistencePostgresContext>));
            if (descriptor != null)
                services.Remove(descriptor);

            services.AddDbContext<PersistencePostgresContext>(options =>
               options.UseNpgsql(connectionString));

			services.AddLogging(builder => builder.AddConsole());

			services.RemoveAll<IHttpClientFactory>();
            services.AddSingleton<IHttpClientFactory>((provider) =>
            {
                return new TestHttpClientFactory(this, provider.GetRequiredService<IConfiguration>());
            });
            services.AddHttpClient();
            services.AddPersistenceClients();

            var serviceProvider = services.BuildServiceProvider();

            using var scope = serviceProvider.CreateScope();
            var scopedServices = scope.ServiceProvider;

            var dbContext = scopedServices.GetRequiredService<PersistencePostgresContext>();
            dbContext.Database.EnsureCreatedAndMigrated();
            dbContext.SaveChanges();
        });
    }

    public override async ValueTask DisposeAsync()
    {
        var dbContext = new PersistencePostgresContext(
           new DbContextOptionsBuilder<PersistencePostgresContext>()
              .UseNpgsql(connectionString)
              .Options);

        await dbContext.Database.EnsureDeletedAsync();

        GC.SuppressFinalize(this);
    }
}