package main

import "time"

type TimeProvider interface {
	Now() time.Time
	Sleep(d time.Duration)
	NewTicker(d time.Duration) Ticker
}

type Ticker interface {
	C() <-chan time.Time
	Stop()
}

type realTimeProvider struct{}

func (realTimeProvider) Now() time.Time                   { return time.Now() }
func (realTimeProvider) Sleep(d time.Duration)            { time.Sleep(d) }
func (realTimeProvider) NewTicker(d time.Duration) Ticker { return realTicker{time.NewTicker(d)} }

type realTicker struct {
	*time.Ticker
}

func (rt realTicker) C() <-chan time.Time { return rt.Ticker.C }

// Return ticker for cron which tick at 0 and ticker for reloading config ticking 10 secounds before
func createTickers(tp TimeProvider) (<-chan time.Time, <-chan time.Time) {
	nextTick := func(targetSecond int) time.Duration {
		now := tp.Now()
		next := now.Truncate(time.Minute).Add(time.Duration(targetSecond) * time.Second)
		if !next.After(now) {
			next = next.Add(time.Minute)
		}
		return next.Sub(now)
	}

	tickAt := func(targetSecond int) <-chan time.Time {
		ch := make(chan time.Time)
		go func() {
			tp.Sleep(nextTick(targetSecond))
			ticker := tp.NewTicker(time.Minute)
			for {
				ch <- tp.Now()
				<-ticker.C()
			}
		}()
		return ch
	}

	return tickAt(0), tickAt(50)
}
