using JobTrackerApi.Data;
using JobTrackerApi.Services;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Moq;
using Xunit;

namespace JobTrackerApi.Tests;

public sealed class StartupSchemaOwnershipTests
{
    [Fact]
    public void Every_model_table_has_exactly_one_creation_owner()
    {
        using var connection = new SqliteConnection("Data Source=:memory:");
        var currentUser = new Mock<ICurrentUserService>();
        currentUser.SetupGet(service => service.UserId).Returns((string?)null);
        using var db = new JobTrackerContext(
            new DbContextOptionsBuilder<JobTrackerContext>().UseSqlite(connection).Options,
            currentUser.Object);

        var modelTables = db.Model.GetEntityTypes()
            .Select(entity => entity.GetTableName())
            .Where(table => table is not null)
            .Cast<string>()
            .ToHashSet(StringComparer.Ordinal);

        var overlap = StartupSchemaOwnership.MigrationOwnedTables
            .Intersect(StartupSchemaOwnership.ReconcilerOwnedTables, StringComparer.Ordinal)
            .OrderBy(table => table)
            .ToArray();
        var classified = StartupSchemaOwnership.MigrationOwnedTables
            .Concat(StartupSchemaOwnership.ReconcilerOwnedTables)
            .ToHashSet(StringComparer.Ordinal);

        Assert.Empty(overlap);
        Assert.Empty(modelTables.Except(classified, StringComparer.Ordinal));
        Assert.Empty(classified.Except(modelTables, StringComparer.Ordinal));
    }

    [Fact]
    public void Compatibility_bootstraps_do_not_create_a_second_current_owner()
    {
        Assert.All(
            StartupSchemaOwnership.MigrationCompatibilityBootstrapTables,
            table => Assert.True(
                StartupSchemaOwnership.MigrationOwnedTables.Contains(table) ^
                StartupSchemaOwnership.ReconcilerOwnedTables.Contains(table)));
    }
}
