using Predictalytics.Hosting;

namespace Predictalytics.Application.Tests.Hosting;

/// <summary>
/// <see cref="PredictalyticsOptions.IsPubliclyBound"/> entscheidet, ob die schreibenden
/// API-Endpunkte ueberhaupt bereitgestellt werden und ob Swagger offen liegt. Ein falsches
/// Ergebnis ist deshalb kein Schoenheitsfehler, sondern eine offene Steuerschnittstelle.
/// </summary>
public class PredictalyticsOptionsTests
{
    [Theory]
    [InlineData("localhost")]
    [InlineData("LOCALHOST")]      // Schreibweise darf nicht entscheiden
    [InlineData("LocalHost")]
    [InlineData("127.0.0.1")]
    [InlineData("::1")]
    [InlineData("  localhost  ")]  // Leerraum aus dem Eingabefeld
    [InlineData("")]               // leer = Vorgabe = lokal
    [InlineData("   ")]
    public void IsPubliclyBound_is_false_for_loopback(string host)
    {
        var options = new PredictalyticsOptions { WebserverHost = host };
        Assert.False(options.IsPubliclyBound);
    }

    [Theory]
    [InlineData("0.0.0.0")]
    [InlineData("::")]
    [InlineData("192.168.178.10")]
    [InlineData("10.0.0.5")]
    [InlineData("predictalytics.example.com")]
    public void IsPubliclyBound_is_true_for_everything_else(string host)
    {
        var options = new PredictalyticsOptions { WebserverHost = host };
        Assert.True(options.IsPubliclyBound);
    }

    [Fact]
    public void WebserverUrl_falls_back_to_localhost_when_host_is_blank()
    {
        var options = new PredictalyticsOptions { WebserverHost = "   ", WebserverPort = 5000 };
        Assert.Equal("http://localhost:5000", options.WebserverUrl);
    }

    [Fact]
    public void WebserverUrl_combines_host_and_port()
    {
        var options = new PredictalyticsOptions { WebserverHost = "0.0.0.0", WebserverPort = 8080 };
        Assert.Equal("http://0.0.0.0:8080", options.WebserverUrl);
    }

    [Fact]
    public void ConnectionString_honours_the_configured_ssl_mode()
    {
        var options = new PredictalyticsOptions
        {
            DbServer = "db.example.com",
            DbName = "predictalytics",
            DbUser = "app",
            DbPassword = "secret",
            DbSslMode = MySqlConnector.MySqlSslMode.Preferred
        };

        var builder = new MySqlConnector.MySqlConnectionStringBuilder(options.ConnectionString);
        Assert.Equal(MySqlConnector.MySqlSslMode.Preferred, builder.SslMode);
        Assert.Equal("predictalytics", builder.Database);
    }

    /// <summary>
    /// Die Setter ignorieren leere Werte bewusst — sonst wuerde ein versehentlich geleertes
    /// Eingabefeld die hinterlegten Zugangsdaten verwerfen.
    /// </summary>
    [Fact]
    public void Blank_database_values_do_not_overwrite_existing_ones()
    {
        var options = new PredictalyticsOptions { DbName = "predictalytics", DbUser = "app" };

        options.DbName = "";
        options.DbUser = "   ";

        Assert.Equal("predictalytics", options.DbName);
        Assert.Equal("app", options.DbUser);
    }
}
