package manage

import (
	"math"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/store/schedule"
)

func TestNextIntervalOccurrence(t *testing.T) {
	t.Parallel()

	anchor := time.Date(2026, 4, 18, 8, 0, 0, 0, time.UTC)
	next, err := schedule.NextIntervalOccurrence(anchor, 300, anchor.Add(11*time.Minute))
	require.NoError(t, err)
	require.Equal(t, anchor.Add(15*time.Minute), next)
}

func TestNextOccurrenceAfterKeepsIntervalErrorContract(t *testing.T) {
	t.Parallel()

	anchor := time.Date(2026, 4, 18, 8, 0, 0, 0, time.UTC)
	tooLarge := int64(math.MaxInt64/int64(time.Second)) + 1
	for _, testCase := range []struct {
		name            string
		intervalSeconds int64
		expectedError   string
	}{
		{
			name:            "positive",
			intervalSeconds: 0,
			expectedError:   "interval_seconds must be positive",
		},
		{
			name:            "too large",
			intervalSeconds: tooLarge,
			expectedError:   "interval_seconds is too large",
		},
	} {
		testCase := testCase
		t.Run(testCase.name, func(t *testing.T) {
			t.Parallel()
			_, err := nextOccurrenceAfter(definitionRecord{
				ID:              "trg_invalid_interval",
				TimeMode:        TimeModeInterval,
				AnchorAt:        &anchor,
				IntervalSeconds: &testCase.intervalSeconds,
			}, anchor)
			require.EqualError(t, err, testCase.expectedError)
		})
	}
}

func TestNextCronOccurrenceAfterSkipsDSTGap(t *testing.T) {
	t.Parallel()

	location, err := time.LoadLocation("America/New_York")
	require.NoError(t, err)

	after := time.Date(2026, 3, 8, 1, 59, 0, 0, location)
	next, err := schedule.NextCronOccurrenceAfter("30 2 * * *", "America/New_York", after)
	require.NoError(t, err)

	require.Equal(t, time.Date(2026, 3, 9, 6, 30, 0, 0, time.UTC), next)
}

func TestNextCronOccurrenceAfterReturnsBothDSTFoldOccurrences(t *testing.T) {
	t.Parallel()

	location, err := time.LoadLocation("America/New_York")
	require.NoError(t, err)

	after := time.Date(2026, 11, 1, 0, 59, 0, 0, location)
	first, err := schedule.NextCronOccurrenceAfter("30 1 * * *", "America/New_York", after)
	require.NoError(t, err)
	require.Equal(t, time.Date(2026, 11, 1, 5, 30, 0, 0, time.UTC), first)

	second, err := schedule.NextCronOccurrenceAfter("30 1 * * *", "America/New_York", first)
	require.NoError(t, err)
	require.Equal(t, time.Date(2026, 11, 1, 6, 30, 0, 0, time.UTC), second)
}
