using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace TrajectoryPlanningVisualization;

public sealed class BoundedCycleHistory
{
    private readonly object sync = new object();
    private readonly int capacity;
    private readonly Queue<VisualizationCycleSummary> entries = new Queue<VisualizationCycleSummary>();
    private readonly HashSet<long> versions = new HashSet<long>();

    public BoundedCycleHistory(int capacity)
    {
        if (capacity <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(capacity));
        }

        this.capacity = capacity;
    }

    public void Add(VisualizationCycleSummary summary)
    {
        if (summary == null)
        {
            throw new ArgumentNullException(nameof(summary));
        }

        lock (sync)
        {
            if (!versions.Add(summary.CycleVersion))
            {
                return;
            }

            entries.Enqueue(summary);
            while (entries.Count > capacity)
            {
                VisualizationCycleSummary removed = entries.Dequeue();
                versions.Remove(removed.CycleVersion);
            }
        }
    }

    public IReadOnlyList<VisualizationCycleSummary> Snapshot()
    {
        lock (sync)
        {
            return new ReadOnlyCollection<VisualizationCycleSummary>(
                new List<VisualizationCycleSummary>(entries));
        }
    }
}
