using System.Reflection;
using Dapper;
using DbUp;
using Npgsql;

namespace Books.Api.EventFlow.Infrastructure;

public static class DatabaseMigrator
{
    public static void Migrate(string connectionString)
    {
        EnsureDatabaseExists(connectionString);

        var upgrader = DeployChanges.To
            .PostgresqlDatabase(connectionString)
            .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
            .LogToConsole()
            .Build();

        var result = upgrader.PerformUpgrade();
        if (!result.Successful)
            throw result.Error;
    }

    private static void EnsureDatabaseExists(string connectionString)
    {
        var builder = new NpgsqlConnectionStringBuilder(connectionString);
        var database = builder.Database;
        builder.Database = "postgres";

        using var connection = new NpgsqlConnection(builder.ConnectionString);
        connection.Open();

        var exists = connection.ExecuteScalar<bool>(
            "SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = @db)",
            new { db = database });

        if (!exists)
        {
            connection.Execute($"CREATE DATABASE \"{database}\"");
        }
    }
}
