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

namespace Persistence.IntegrationTests;
public class WebAppFactoryFixture : WebApplicationFactory<Startup>
{
    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();
		});

		builder.ConfigureServices(services =>
        {
            var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistenceDbContext>));
            if (descriptor != null)
                services.Remove(descriptor);
			services.AddDbContext<PersistenceDbContext>(options =>
               options.UseNpgsql(connectionString));

			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<PersistenceDbContext>();
            dbContext.Database.EnsureCreatedAndMigrated();
            dbContext.SaveChanges();
		});
    }

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

        await dbContext.Database.EnsureDeletedAsync();
    }
}