using Dapper;
using KArtSell.BuildingBlocks.Time;
using Microsoft.Extensions.Logging;
using Npgsql;
using System;
using Xunit;

namespace KArtSell.Integration.Tests;

[CollectionDefinition("Database")]
public class DatabaseFixtureCollection : ICollectionFixture<DatabaseFixture>
{
    // This is just a marker class for xUnit collection fixtures
}

public class DatabaseFixture : IAsyncLifetime
{
    private readonly string _connectionString;
    public NpgsqlDataSource DataSource { get; private set; } = null!;

    public DatabaseFixture()
    {
        _connectionString = TestDatabaseConnection.GetConnectionString();
    }

    public async Task InitializeAsync()
    {
        var dataSourceBuilder = new NpgsqlDataSourceBuilder(_connectionString);
        DataSource = dataSourceBuilder.Build();

        // Verify connection works
        await using var conn = await DataSource.OpenConnectionAsync();
        await conn.ExecuteAsync("SELECT 1");
    }

    public async Task DisposeAsync()
    {
        await DataSource.DisposeAsync();
    }

    public ILogger<T> Logger<T>() where T : class
    {
        return new XunitLogger<T>();
    }

    public IClock Clock()
    {
        return new TestClock();
    }
}

internal sealed class TestClock : IClock
{
    public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
}

internal sealed class XunitLogger<T> : ILogger<T>
{
    public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
    public bool IsEnabled(LogLevel logLevel) => true;
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
        Func<TState, Exception?, string> formatter) { }
}
