using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System.Diagnostics;

namespace DD.Persistence.Database.Postgres;
public static class EFExtensionsInitialization
{
    public static void EnsureCreatedAndMigrated(this DatabaseFacade db)
    {
        var connectionString = db.GetConnectionString();
        Trace.TraceInformation($"connectionString: {connectionString}");
        db.SetCommandTimeout(TimeSpan.FromMinutes(5));
        if (db.EnsureCreated())
        {
            Trace.TraceInformation("Creating DB");
            Console.WriteLine("Creating DB");
            db.CreateMigrationTable();
            db.WriteMigrationsInfo();
        }
        else
        {
            Trace.TraceInformation("Migrating DB");
            db.SetCommandTimeout(TimeSpan.FromMinutes(20));
            Console.WriteLine("db.Migrate()");
            db.Migrate();
        }
    }

    private static void CreateMigrationTable(this DatabaseFacade db)
    {
        var sqlCreateMigrationTable =
            $"CREATE TABLE public.\"__EFMigrationsHistory\" " +
            $"(\"MigrationId\" varchar(150) NOT NULL, " +
            $" \"ProductVersion\" varchar(32) NOT NULL, " +
            $" CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY (\"MigrationId\"));";
        db.ExecuteSqlRaw(sqlCreateMigrationTable);
    }

    private static void WriteMigrationsInfo(this DatabaseFacade db)
    {
        var efVersion = db.GetType().Assembly.GetName().Version!;
        var efVersionString = $"{efVersion.Major}.{efVersion.Minor}.{efVersion.Build}";

        var migrations = db.GetPendingMigrations()
            .Select(migration => $" ('{migration}', '{efVersionString}')");

        if (migrations.Any())
        {
            var sqlAddLastMigration =
                $"INSERT INTO public.\"__EFMigrationsHistory\" " +
                $"(\"MigrationId\", \"ProductVersion\") " +
                $"VALUES {string.Join(',', migrations)};";
            db.ExecuteSqlRaw(sqlAddLastMigration);
        }
    }
}