using System.Reflection;
using DbUp;

namespace GmRelay.Bot.Infrastructure.Database;

/// <summary>
/// Runs embedded SQL migrations via DbUp on application startup.
/// Scripts are embedded as resources from the Migrations/ folder.
/// NOTE: We read the connection string from IConfiguration directly,
/// because NpgsqlDataSource.ConnectionString strips the password by default.
/// </summary>
public sealed class DbMigrator(IConfiguration configuration, ILogger<DbMigrator> logger)
{
    public void MigrateUp()
    {
        var connectionString = configuration.GetConnectionString("gmrelaydb")
            ?? throw new InvalidOperationException("ConnectionStrings:gmrelaydb is required.");

        EnsureDatabase.For.PostgresqlDatabase(connectionString);

        var upgrader = DeployChanges.To
            .PostgresqlDatabase(connectionString)
            .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains(".Migrations."))
            .WithTransactionPerScript()
            .LogToConsole()
            .Build();

        var result = upgrader.PerformUpgrade();

        if (!result.Successful)
        {
            var ex = result.Error;
            logger.LogCritical(ex, "Database migration failed");
            throw ex;
        }

        var count = result.Scripts.Count();
        logger.LogInformation("Database migrations applied successfully. {Count} scripts executed", count);
    }
}
