using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Meezi.API;
using Meezi.Infrastructure.Data;

namespace Meezi.API.Tests.Integration;

public class MeeziWebApplicationFactory : WebApplicationFactory<Program>
{
    protected override IHost CreateHost(IHostBuilder builder)
    {
        var app = Program.BuildWebApplication(
            Array.Empty<string>(),
            ConfigureTestingBeforeServices,
            ConfigureTestingAfterServices);
        app.StartAsync().GetAwaiter().GetResult();
        return app;
    }

    private static void ConfigureTestingBeforeServices(WebApplicationBuilder webBuilder)
    {
        webBuilder.Environment.EnvironmentName = "Testing";
        webBuilder.WebHost.UseTestServer();
        webBuilder.Configuration.AddInMemoryCollection(new Dictionary<string, string?>
        {
            ["Testing:Enabled"] = "true",
            ["Testing:SkipSeed"] = "true",
            ["RUN_MIGRATIONS"] = "false",
            ["ConnectionStrings:Redis"] = "127.0.0.1:6379"
        });
    }

    private static void ConfigureTestingAfterServices(WebApplicationBuilder webBuilder)
    {
        var dbDescriptor = webBuilder.Services.SingleOrDefault(d =>
            d.ServiceType == typeof(DbContextOptions<AppDbContext>));
        if (dbDescriptor is not null)
            webBuilder.Services.Remove(dbDescriptor);

        webBuilder.Services.AddDbContext<AppDbContext>(options =>
            options.UseInMemoryDatabase("meezi_test_db"));
    }
}
