using System.Diagnostics;

namespace ScadaLink.PerformanceTests;

/// <summary>
/// WP-4 (Phase 8): Performance test framework for staggered startup.
/// Target scale: 10 sites, 500 machines, 75 tags each.
/// These are framework/scaffold tests — actual perf runs are manual.
/// </summary>
public class StaggeredStartupTests
{
    /// <summary>
    /// Target: 500 instance configurations created and validated within time budget.
    /// Verifies the staggered startup model can handle the target instance count.
    /// </summary>
    [Trait("Category", "Performance")]
    [Fact]
    public void StaggeredStartup_500Instances_CompletesWithinBudget()
    {
        // Scaffold: simulate 500 instance creation with staggered delay
        const int instanceCount = 500;
        const int staggerDelayMs = 50; // 50ms between each instance start
        var expectedTotalMs = instanceCount * staggerDelayMs; // ~25 seconds

        var sw = Stopwatch.StartNew();
        var instanceNames = new List<string>(instanceCount);

        for (var i = 0; i < instanceCount; i++)
        {
            // Simulate instance name generation (real startup would create InstanceActor)
            var siteName = $"site-{(i / 50) + 1:D2}";
            var instanceName = $"{siteName}/machine-{(i % 50) + 1:D3}";
            instanceNames.Add(instanceName);
        }

        sw.Stop();

        // Verify all instances were "started"
        Assert.Equal(instanceCount, instanceNames.Count);
        Assert.Equal(instanceCount, instanceNames.Distinct().Count());

        // Verify naming convention
        Assert.All(instanceNames, name => Assert.Contains("/machine-", name));

        // Time budget for name generation should be trivial
        Assert.True(sw.ElapsedMilliseconds < 1000,
            $"Instance name generation took {sw.ElapsedMilliseconds}ms, expected < 1000ms");

        // Verify expected total startup time with staggering
        Assert.True(expectedTotalMs <= 30000,
            $"Expected staggered startup {expectedTotalMs}ms exceeds 30s budget");
    }

    [Trait("Category", "Performance")]
    [Fact]
    public void StaggeredStartup_DistributionAcross10Sites()
    {
        // Verify that 500 instances are evenly distributed across 10 sites
        const int siteCount = 10;
        const int machinesPerSite = 50;
        var sites = new Dictionary<string, int>();

        for (var s = 0; s < siteCount; s++)
        {
            var siteId = $"site-{s + 1:D2}";
            sites[siteId] = 0;

            for (var m = 0; m < machinesPerSite; m++)
            {
                sites[siteId]++;
            }
        }

        Assert.Equal(siteCount, sites.Count);
        Assert.All(sites.Values, count => Assert.Equal(machinesPerSite, count));
        Assert.Equal(500, sites.Values.Sum());
    }

    [Trait("Category", "Performance")]
    [Fact]
    public void TagCapacity_75TagsPer500Machines_37500Total()
    {
        // Verify the system can represent 37,500 tag subscriptions
        const int machines = 500;
        const int tagsPerMachine = 75;
        const int totalTags = machines * tagsPerMachine;

        var tagPaths = new HashSet<string>(totalTags);
        for (var m = 0; m < machines; m++)
        {
            for (var t = 0; t < tagsPerMachine; t++)
            {
                tagPaths.Add($"site-{(m / 50) + 1:D2}/machine-{(m % 50) + 1:D3}/tag-{t + 1:D3}");
            }
        }

        Assert.Equal(totalTags, tagPaths.Count);
    }
}
