using Npgsql;
using SatelliteProvider.TestSupport;

namespace SatelliteProvider.IntegrationTests;

public sealed class IntegrationTestDatabaseReset
{
    public static readonly IReadOnlyList<string> TruncateOrder =
        new[] { "route_regions", "route_points", "routes", "regions", "tiles" };

    private readonly string _connectionString;

    public IntegrationTestDatabaseReset(string connectionString)
    {
        if (string.IsNullOrWhiteSpace(connectionString))
        {
            throw new ArgumentException("Connection string must not be empty.", nameof(connectionString));
        }
        _connectionString = connectionString;
    }

    public async Task EnsureCleanStateAsync()
    {
        var environment = Environment.GetEnvironmentVariable(IntegrationTestResetGuard.EnvironmentEnvVar);
        var builder = new NpgsqlConnectionStringBuilder(_connectionString);
        IntegrationTestResetGuard.EnsureGuardPassesOrThrow(environment, builder.Host);

        await using var connection = new NpgsqlConnection(_connectionString);
        await connection.OpenAsync();

        await using var transaction = await connection.BeginTransactionAsync();
        var truncateSql = $"TRUNCATE TABLE {string.Join(", ", TruncateOrder)} RESTART IDENTITY CASCADE";
        await using (var cmd = new NpgsqlCommand(truncateSql, connection, transaction))
        {
            await cmd.ExecuteNonQueryAsync();
        }
        await transaction.CommitAsync();

        Console.WriteLine(
            $"✓ Integration test DB reset complete: truncated [{string.Join(", ", TruncateOrder)}] on {builder.Host}/{builder.Database}");
    }
}
