using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;

namespace StellaOps.Feedser.Merge.Tests;

internal sealed class MetricCollector : IDisposable
{
    private readonly MeterListener _listener;
    private readonly List<MetricMeasurement> _measurements = new();

    public MetricCollector(string meterName)
    {
        if (string.IsNullOrWhiteSpace(meterName))
        {
            throw new ArgumentException("Meter name is required", nameof(meterName));
        }

        _listener = new MeterListener
        {
            InstrumentPublished = (instrument, listener) =>
            {
                if (instrument.Meter.Name == meterName)
                {
                    listener.EnableMeasurementEvents(instrument);
                }
            }
        };

        _listener.SetMeasurementEventCallback<long>((instrument, measurement, tags, state) =>
        {
            var tagArray = new KeyValuePair<string, object?>[tags.Length];
            for (var i = 0; i < tags.Length; i++)
            {
                tagArray[i] = tags[i];
            }

            _measurements.Add(new MetricMeasurement(instrument.Name, measurement, tagArray));
        });

        _listener.Start();
    }

    public IReadOnlyList<MetricMeasurement> Measurements => _measurements;

    public void Dispose()
    {
        _listener.Dispose();
    }

    internal sealed record MetricMeasurement(
        string Name,
        long Value,
        IReadOnlyList<KeyValuePair<string, object?>> Tags);
}
