using System.Globalization;
using System.Text.Json;
using Npgsql;
using Xunit.Abstractions;
namespace MeterVault.Integration.Tests.Performance;
///
/// Loads the synthetic raw dataset into a database an app has already migrated — the pre-rework app (c0f52db) or the
/// current one — for the page-level before/after comparison (brief §9.10). Nothing derived is written: the next start
/// of that app rebuilds consumption (and, in the new app, rollups and coverage) itself, because the load clears the
/// stored normalization revision. Writes manifest-<label>.json with the meter and type ids the page
/// timings address.
///
///
/// METERVAULT_PERF=1 METERVAULT_PERF_LOAD_DB="Host=…;Port=…;Database=metervault;Username=metervault;Password=metervault"
/// dotnet test tests/Integration.Tests --filter "FullyQualifiedName~Performance.SyntheticLoadTests". The dataset ends at
/// METERVAULT_PERF_NOW, or at the current time, so the pages see recent live data.
///
[Trait("Category", "Performance")]
public sealed class SyntheticLoadTests(ITestOutputHelper output)
{
[PerfLoadFact]
public async Task Load_the_synthetic_dataset_into_an_app_migrated_database()
{
var settings = PerfSettings.Current;
using var log = new PerfLog(settings, "load", output);
var target = settings.LoadDatabase!;
await using (var connection = new NpgsqlConnection(target))
{
await connection.OpenAsync();
var migrated = await PerfDatabase.ScalarAsync(connection, "SELECT to_regclass('meter') IS NOT NULL AND to_regclass('app_setting') IS NOT NULL");
Assert.True(migrated is true, "The target database is not migrated: start the app against it once first.");
var schema = await PerfDatabase.ScalarAsync(connection, "SELECT to_regclass('consumption_rollup') IS NOT NULL") is true ? "analysis rework" : "pre-rework (c0f52db)";
log.Write($"Target schema: {schema}");
}
// The current minute, so the hourly live meters end just before the pages are timed.
var now = settings.Now ?? DateTimeOffset.UtcNow.AddSeconds(-DateTimeOffset.UtcNow.Second);
var zone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
var manifest = await SyntheticDataset.LoadAsync(target, now, zone, settings.Scale, log.Write);
Directory.CreateDirectory(settings.OutputDirectory);
var path = Path.Combine(settings.OutputDirectory, $"manifest-{settings.Label}.json");
await File.WriteAllTextAsync(path, JsonSerializer.Serialize(manifest, DatasetManifest.Json));
log.Write(string.Create(CultureInfo.InvariantCulture, $"Loaded {manifest.MeterCount} meters and {manifest.Readings:N0} readings; manifest {path}"));
}
}