using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.DependencyInjection;
using Tiku.IntegrationTests.Api;
using Tiku.Infrastructure.Persistence;

namespace Tiku.IntegrationTests;

public sealed class MigrationExecutionTests
{
    [Fact]
    public async Task Api_test_database_uses_postgresql_and_applies_every_migration()
    {
        await using var factory = new ApiTestFactory();
        using var scope = factory.Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();

        var appliedMigrations = await dbContext.Database.GetAppliedMigrationsAsync();
        var expectedMigrations = dbContext.Database.GetMigrations();

        Assert.Equal("Npgsql.EntityFrameworkCore.PostgreSQL", dbContext.Database.ProviderName);
        Assert.Equal(expectedMigrations, appliedMigrations);
        Assert.NotEmpty(appliedMigrations);
        Assert.True(await dbContext.Database.CanConnectAsync());
    }

    [Fact]
    public async Task Migration_script_contains_database_guard_triggers()
    {
        await using var factory = new ApiTestFactory();
        using var scope = factory.Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
        var migrator = dbContext.GetService<IMigrator>();

        var script = migrator.GenerateScript();

        Assert.Contains("drop trigger if exists trg_tenant_question_references_platform_or_self_owner", script);
        Assert.Contains("create or replace function tiku_guard_tenant_question_reference()", script);
        Assert.Contains("create trigger trg_tenant_question_references_platform_or_self_owner", script);
        Assert.Contains("drop trigger if exists trg_taxonomy_nodes_parent_platform_or_self_owner", script);
        Assert.Contains("create or replace function tiku_guard_taxonomy_parent_owner()", script);
        Assert.Contains("create trigger trg_taxonomy_nodes_parent_platform_or_self_owner", script);
        Assert.Contains("drop trigger if exists trg_saas_offering_versions_published_immutable", script);
        Assert.Contains("create or replace function tiku_guard_saas_offering_version_immutable()", script);
        Assert.Contains("create trigger trg_saas_offering_versions_published_immutable", script);
        Assert.Contains("create or replace function tiku_guard_saas_offering_version_child_immutable()", script);
        Assert.Contains("create trigger trg_saas_offering_version_features_published_immutable", script);
        Assert.Contains("create trigger trg_saas_offering_version_limits_published_immutable", script);
        Assert.Contains("create trigger trg_tenant_saas_subscriptions_base_plan", script);
        Assert.Contains("create trigger trg_tenant_saas_subscription_items_offering_type", script);
        Assert.Contains("create or replace function tiku_guard_saas_subscription_offering_type()", script);
    }
}
