package monitor

import (
	"local/rssmon3/config"
	"log"
	"time"
)

type Monitor struct {
	queue    *Queue
	Incoming chan *Item
	Outgoing chan *Item
	config.Stoppable
}

func New() (*Monitor, error) {
	q, err := newQueue()
	return &Monitor{
		queue:    q,
		Incoming: make(chan *Item),
		Outgoing: make(chan *Item),
	}, err
}

func (m *Monitor) Run() error {
	for {
		select {
		case <-m.Stopped():
			return nil
		case i := <-m.enqueued():
			m.enqueue(i)
			continue
		case <-m.triggered():
			m.trigger()
		}
	}
}

func (m *Monitor) enqueued() chan *Item {
	return m.Incoming
}

func (m *Monitor) enqueue(i *Item) {
	m.queue.Push(i)
}

func (m *Monitor) triggered() <-chan time.Time {
	if m.queue.Len() < 1 {
		return nil
	}
	top := m.queue.Peek()
	if top == nil {
		return nil
	}
	block := time.Until(top.Last().Add(top.Interval()))
	log.Printf("[triggered] blocking %v until next task", block)
	return time.After(time.Until(top.Last().Add(top.Interval())))
}

func (m *Monitor) trigger() {
	i := m.queue.Pop()
	if i == nil {
		return
	}
	m.Outgoing <- i
	i.Mark()
	m.queue.Push(i)
}
