using FluentAssertions;
using SatelliteProvider.TestSupport;

namespace SatelliteProvider.Tests.TestSupport;

public class IntegrationTestResetGuardTests
{
    [Fact]
    public void EnsureGuardPassesOrThrow_ProductionEnvironment_Throws()
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Production", "postgres");

        // Assert
        act.Should().Throw<InvalidOperationException>()
            .WithMessage("*ASPNETCORE_ENVIRONMENT*Production*expected*Testing*");
    }

    [Fact]
    public void EnsureGuardPassesOrThrow_StagingEnvironment_Throws()
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Staging", "postgres");

        // Assert
        act.Should().Throw<InvalidOperationException>()
            .WithMessage("*Staging*expected*Testing*");
    }

    [Fact]
    public void EnsureGuardPassesOrThrow_MissingEnvironment_Throws()
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow(null, "postgres");

        // Assert
        act.Should().Throw<InvalidOperationException>()
            .WithMessage("*not set*expected*Testing*");
    }

    [Fact]
    public void EnsureGuardPassesOrThrow_TestingEnvironment_AllowedHost_DoesNotThrow()
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Testing", "postgres");

        // Assert
        act.Should().NotThrow();
    }

    [Theory]
    [InlineData("postgres")]
    [InlineData("Postgres")]
    [InlineData("POSTGRES")]
    [InlineData("localhost")]
    [InlineData("127.0.0.1")]
    public void EnsureGuardPassesOrThrow_TestingEnvironment_AcceptsAllowedHosts(string host)
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Testing", host);

        // Assert
        act.Should().NotThrow();
    }

    [Theory]
    [InlineData("prod.example.com")]
    [InlineData("rds.amazonaws.com")]
    [InlineData("db.staging.internal")]
    public void EnsureGuardPassesOrThrow_TestingEnvironment_RejectsDisallowedHosts(string host)
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Testing", host);

        // Assert
        act.Should().Throw<InvalidOperationException>()
            .WithMessage($"*Host '{host}' is not in the allowed-host list*");
    }

    [Fact]
    public void EnsureGuardPassesOrThrow_TestingEnvironment_MissingHost_Throws()
    {
        // Act
        var act = () => IntegrationTestResetGuard.EnsureGuardPassesOrThrow("Testing", null);

        // Assert
        act.Should().Throw<InvalidOperationException>()
            .WithMessage("*connection string has no Host*");
    }

    [Fact]
    public void AllowedHosts_IsImmutableContract()
    {
        // Assert
        IntegrationTestResetGuard.AllowedHosts.Should().BeEquivalentTo(new[] { "postgres", "localhost", "127.0.0.1" });
    }
}
