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

namespace AsbCloudDb
{
    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}')");

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