namespace NATS.Server.Raft;

/// <summary>
/// Represents a snapshot checkpoint that can be assembled from chunks during streaming install.
/// Go reference: raft.go:3200-3400 (CreateSnapshotCheckpoint), raft.go:3500-3700 (installSnapshot)
/// </summary>
public sealed class RaftSnapshotCheckpoint
{
    /// <summary>
    /// The log index this snapshot covers up to.
    /// </summary>
    public long SnapshotIndex { get; init; }

    /// <summary>
    /// The term of the last entry included in this snapshot.
    /// </summary>
    public int SnapshotTerm { get; init; }

    /// <summary>
    /// Complete snapshot data (used when not assembled from chunks).
    /// </summary>
    public byte[] Data { get; init; } = [];

    /// <summary>
    /// Whether the snapshot has been fully assembled from chunks.
    /// </summary>
    public bool IsComplete { get; private set; }

    private readonly List<byte[]> _chunks = [];

    /// <summary>
    /// Adds a chunk of snapshot data for streaming assembly.
    /// </summary>
    public void AddChunk(byte[] chunk) => _chunks.Add(chunk);

    /// <summary>
    /// Assembles all added chunks into a single byte array.
    /// If no chunks were added, returns the initial <see cref="Data"/>.
    /// Marks the checkpoint as complete after assembly.
    /// </summary>
    public byte[] Assemble()
    {
        if (_chunks.Count == 0)
            return Data;

        var total = _chunks.Sum(c => c.Length);
        var result = new byte[total];
        var offset = 0;
        foreach (var chunk in _chunks)
        {
            chunk.CopyTo(result, offset);
            offset += chunk.Length;
        }

        IsComplete = true;
        return result;
    }
}
