package planner

import (
	"testing"
	"time"

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

type testClock struct {
	now   time.Time
	calls int
}

func (c *testClock) Now() time.Time {
	c.calls++
	return c.now
}

func TestEnsureSnapshotTSO(t *testing.T) {
	now := time.Date(2026, time.August, 2, 10, 11, 12, 987654321, time.FixedZone("test-zone", 8*60*60))
	clock := &testClock{now: now}

	tso, err := EnsureSnapshotTSO(0, clock)
	require.NoError(t, err)
	expectedTime := now.UTC().Truncate(time.Millisecond)
	require.Equal(t, uint64(expectedTime.UnixMilli())<<tsoLogicalBits, tso)
	require.Equal(t, 1, clock.calls)

	retryClock := &testClock{now: now.Add(time.Hour)}
	reused, err := EnsureSnapshotTSO(tso, retryClock)
	require.NoError(t, err)
	require.Equal(t, tso, reused)
	require.Zero(t, retryClock.calls, "retry must not read the clock after T is persisted")
}

func TestEnsureSnapshotTSORejectsInvalidTime(t *testing.T) {
	_, err := EnsureSnapshotTSO(0, nil)
	require.ErrorIs(t, err, ErrInvalidSnapshotTime)

	_, err = EnsureSnapshotTSO(0, &testClock{now: time.UnixMilli(-1)})
	require.ErrorIs(t, err, ErrInvalidSnapshotTime)
}
