using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Skills;

namespace NeonSprawl.Server.Tests.Game.PositionState;

/// <summary>Integration host with <see cref="PositionStateServiceCollectionExtensions.NeonSprawlConnectionStringName"/> bound from environment.</summary>
public sealed class PostgresWebApplicationFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        var cs = Environment.GetEnvironmentVariable("ConnectionStrings__NeonSprawl");
        PostgresDockerHelper.EnsurePostgresOrStartDockerBlocking(cs);
        if (string.IsNullOrWhiteSpace(cs))
        {
            throw new InvalidOperationException(
                "Set ConnectionStrings__NeonSprawl for Postgres integration tests (see server/README.md).");
        }

        builder.UseEnvironment("Testing");

        var skillsDir = SkillCatalogPathResolution.TryDiscoverSkillsDirectory(AppContext.BaseDirectory)
            ?? throw new InvalidOperationException(
                "Could not discover repo content/skills from AppContext.BaseDirectory; run tests from the neon-sprawl clone.");
        var masteryDir = MasteryCatalogPathResolution.TryDiscoverMasteryDirectory(AppContext.BaseDirectory)
            ?? throw new InvalidOperationException(
                "Could not discover repo content/mastery from AppContext.BaseDirectory; run tests from the neon-sprawl clone.");
        builder.UseSetting("Content:SkillsDirectory", skillsDir);
        builder.UseSetting("Content:MasteryDirectory", masteryDir);

        builder.ConfigureAppConfiguration((_, config) =>
        {
            config.AddInMemoryCollection(new Dictionary<string, string?>
            {
                ["ConnectionStrings:NeonSprawl"] = cs.Trim(),
            });
        });
    }
}
