package innerring

import (
	"testing"

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

func TestEpochTimer(t *testing.T) {
	t.Parallel()
	neh := &testNewEpochHandler{}
	epochState := &testEpochState{
		counter:  99,
		duration: 10,
	}

	args := &epochTimerArgs{
		newEpochHandlers: []newEpochHandler{neh.Handle},
		epoch:            epochState,
	}
	et := newEpochTimer(args)
	err := et.Reset()
	require.NoError(t, err, "failed to reset timer")

	et.Tick(100)
	require.Equal(t, 0, neh.called, "invalid new epoch handler calls")

	et.Tick(101)
	require.Equal(t, 0, neh.called, "invalid new epoch handler calls")

	et.Tick(102)
	require.Equal(t, 0, neh.called, "invalid new epoch handler calls")

	et.Tick(103)
	require.Equal(t, 0, neh.called, "invalid new epoch handler calls")

	var h uint32
	for h = 104; h < 109; h++ {
		et.Tick(h)
		require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
	}

	et.Tick(109)
	require.Equal(t, 1, neh.called, "invalid new epoch handler calls")

	et.Tick(110)
	require.Equal(t, 1, neh.called, "invalid new epoch handler calls")

	et.Tick(111)
	require.Equal(t, 1, neh.called, "invalid new epoch handler calls")

	et.Tick(112)
	require.Equal(t, 1, neh.called, "invalid new epoch handler calls")

	et.Tick(113)
	require.Equal(t, 1, neh.called, "invalid new epoch handler calls")

	for h = 114; h < 119; h++ {
		et.Tick(h)
		require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
	}
	et.Tick(120)
	require.Equal(t, 2, neh.called, "invalid new epoch handler calls")
}

type testNewEpochHandler struct {
	called int
}

func (h *testNewEpochHandler) Handle() {
	h.called++
}

type testEpochState struct {
	counter  uint64
	duration uint64
}

func (s *testEpochState) EpochCounter() uint64 {
	return s.counter
}

func (s *testEpochState) EpochDuration() uint64 {
	return s.duration
}