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.API;
using DD.Persistence.Client;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Postgres;
using RestSharp;
using DD.Persistence.App;

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 dbConnection = config.Build().GetSection("DbConnection").Get<DbConnection>()!;
            connectionString = dbConnection.GetConnectionString();
            //connectionString = "Host=postgres;Port=5442;Username=postgres;Password=postgres;Database=persistence";
        });

        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);
			});

            services.AddSingleton<PersistenceClientFactory>();

            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);
    }
}