package status

import (
	"sync"
	"time"
)

type ste struct {
	status Status
	error  error
}

type backgroundMonitor struct {
	l        sync.Locker
	m        ResourceMonitor
	interval time.Duration
	cache    map[ResourceRef]ste
}

func NewBackgroundMonitor(m ResourceMonitor, interval time.Duration) ResourceMonitor {
	return &backgroundMonitor{
		&sync.Mutex{},
		m,
		interval,
		map[ResourceRef]ste{},
	}
}

func (m *backgroundMonitor) Get(ref ResourceRef) (Status, error) {
	m.l.Lock()
	defer m.l.Unlock()
	if ret, ok := m.cache[ref]; ok {
		return ret.status, ret.error
	}
	m.cache[ref] = ste{StatusNotFound, nil}
	go func() {
		st, err := m.m.Get(ref)
		m.l.Lock()
		m.cache[ref] = ste{st, err}
		m.l.Unlock()
		if IsStatusTerminal(st) {
			return
		}
		time.Sleep(m.interval)
	}()
	return StatusNotFound, nil
}
