package uisession

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

// TestInitialSnapshotAlwaysFirst covers P4-BE-13: the initial snapshot is
// always the first observation on every (re)subscribe, regardless of
// intervening mutations. No iteration observes a Change before the initial
// snapshot was read from the Subscription struct (not the channel).
func TestInitialSnapshotAlwaysFirst(t *testing.T) {
	now := time.Date(2026, 7, 16, 0, 0, 0, 0, time.UTC)
	store := NewStore(Options{Now: func() time.Time { return now }})
	expiresAt := now.Add(time.Hour)

	const sessionID = "session-regression"
	const serverID = "server-1"

	for i := 0; i < 100; i++ {
		sub, err := store.Subscribe(sessionID, expiresAt)
		require.NoError(t, err, "iteration %d", i)

		// Initial snapshot MUST be read from the struct BEFORE draining
		// the channel. Any non-empty initial snapshot here would mean the
		// previous iteration's release left a stale Change in the channel.
		if i == 0 {
			require.Equal(t, SubscriptionStateEmpty, sub.Snapshot.State)
		} else {
			require.NotZero(t, sub.Snapshot.Generation, "iteration %d snapshot MUST reflect authoritative state", i)
		}

		// Now mutate + release to set up the next iteration's pre-state.
		_, _ = store.Select(sessionID, expiresAt, serverID)
		_, _ = store.Clear(sessionID)
		sub.Release()
	}
}
