package uisession

import (
	"testing"
	"time"

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

// TestTwoSessionsAreIsolated covers P4-BE-08: a Select on sessionA does
// not deliver to sessionB's Changes channel.
func TestTwoSessionsAreIsolated(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 sessionA = "session-isolation-a"
	const sessionB = "session-isolation-b"

	subA, err := store.Subscribe(sessionA, expiresAt)
	require.NoError(t, err)
	subB, err := store.Subscribe(sessionB, expiresAt)
	require.NoError(t, err)

	_, err = store.Select(sessionA, expiresAt, "server-2")
	require.NoError(t, err)

	// sessionA's Changes has exactly one Selected event for server-2.
	select {
	case change := <-subA.Changes:
		require.Equal(t, ChangeKindSelected, change.Kind)
		require.Equal(t, SubscriptionStateSelected, change.State)
		require.Equal(t, "server-2", change.ActiveServerID)
		require.Equal(t, uint64(1), change.Generation)
	default:
		t.Fatal("sessionA's Changes MUST have a Selected event")
	}

	// sessionB's Changes has no event.
	select {
	case _, ok := <-subB.Changes:
		if ok {
			t.Fatal("sessionB's Changes MUST NOT receive a Selected event for sessionA")
		}
	default:
	}

	// sessionB's subsequent Select(S3) arrives on sessionB only.
	_, err = store.Select(sessionB, expiresAt, "server-3")
	require.NoError(t, err)
	select {
	case change := <-subB.Changes:
		require.Equal(t, ChangeKindSelected, change.Kind)
		require.Equal(t, SubscriptionStateSelected, change.State)
		require.Equal(t, "server-3", change.ActiveServerID)
	default:
		t.Fatal("sessionB's Changes MUST have a Selected event for its own Select")
	}

	select {
	case _, ok := <-subA.Changes:
		if ok {
			t.Fatal("sessionA's Changes MUST NOT receive sessionB's Select")
		}
	default:
	}

	if subA.Release != nil {
		subA.Release()
	}
	if subB.Release != nil {
		subB.Release()
	}
}
