package clock

import (
	"testing"
	"time"

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

func TestRealClock_Now(t *testing.T) {
	c := Real()
	now := c.Now()
	assert.WithinDuration(t, time.Now(), now, time.Second)
}

func TestFakeClock_NowReturnsSetTime(t *testing.T) {
	t0 := time.Date(2026, 5, 5, 10, 0, 0, 0, time.UTC)
	c := NewFake(t0)
	assert.Equal(t, t0, c.Now())
}

func TestFakeClock_Advance(t *testing.T) {
	t0 := time.Date(2026, 5, 5, 10, 0, 0, 0, time.UTC)
	c := NewFake(t0)
	c.Advance(2 * time.Hour)
	assert.Equal(t, t0.Add(2*time.Hour), c.Now())
}

func TestFakeClock_AdvanceConcurrent(t *testing.T) {
	c := NewFake(time.Now())
	done := make(chan struct{})
	go func() {
		for i := 0; i < 1000; i++ {
			c.Advance(time.Microsecond)
		}
		close(done)
	}()
	for i := 0; i < 1000; i++ {
		_ = c.Now()
	}
	<-done
}

func TestFakeClock_Set(t *testing.T) {
	c := NewFake(time.Date(2026, 5, 5, 10, 0, 0, 0, time.UTC))
	t1 := time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC)
	c.Set(t1)
	assert.Equal(t, t1, c.Now())
}

var _ Clock = (*realClock)(nil)
var _ Clock = (*FakeClock)(nil)
var _ = require.New // keep import live; helper used by other packages
