using System.Diagnostics;

namespace NATS.Server.Benchmark.Tests.Harness;

/// <summary>
/// Pre-allocated latency recording buffer with percentile computation.
/// Records elapsed ticks from Stopwatch for each sample.
/// </summary>
public sealed class LatencyTracker
{
    private readonly long[] _samples;
    private int _count;
    private bool _sorted;

    public LatencyTracker(int capacity)
    {
        _samples = new long[capacity];
    }

    public void Record(long elapsedTicks)
    {
        if (_count < _samples.Length)
        {
            _samples[_count++] = elapsedTicks;
            _sorted = false;
        }
    }

    public LatencyPercentiles ComputePercentiles()
    {
        if (_count == 0)
            return new LatencyPercentiles(0, 0, 0, 0, 0);

        if (!_sorted)
        {
            Array.Sort(_samples, 0, _count);
            _sorted = true;
        }

        var ticksPerUs = Stopwatch.Frequency / 1_000_000.0;

        return new LatencyPercentiles(
            P50Us: _samples[Percentile(50)] / ticksPerUs,
            P95Us: _samples[Percentile(95)] / ticksPerUs,
            P99Us: _samples[Percentile(99)] / ticksPerUs,
            MinUs: _samples[0] / ticksPerUs,
            MaxUs: _samples[_count - 1] / ticksPerUs);
    }

    private int Percentile(int p) => Math.Min((int)(_count * (p / 100.0)), _count - 1);
}
