using System;
using System.Threading;

namespace TrajectoryPlanningVisualization;

public sealed class VisualizationFrame
{
    public VisualizationFrame(long version, PlanningVisualizationDynamicSnapshot snapshot)
    {
        Version = version;
        Snapshot = snapshot ?? throw new ArgumentNullException(nameof(snapshot));
    }

    public long Version { get; }
    public PlanningVisualizationDynamicSnapshot Snapshot { get; }
}

public sealed class LatestVisualizationFrameStore
{
    private VisualizationFrame latest;
    private long nextVersion;

    public void Publish(PlanningVisualizationDynamicSnapshot snapshot)
    {
        if (snapshot == null)
        {
            throw new ArgumentNullException(nameof(snapshot));
        }

        long version = Interlocked.Increment(ref nextVersion);
        Interlocked.Exchange(ref latest, new VisualizationFrame(version, snapshot));
    }

    public bool TryReadAfter(long version, out VisualizationFrame frame)
    {
        VisualizationFrame current = Volatile.Read(ref latest);
        if (current == null || current.Version <= version)
        {
            frame = null;
            return false;
        }

        frame = current;
        return true;
    }
}
