package main

import (
	"errors"
	"time"

	"code.justin.tv/d8a/pg-healthcheck/common"
)

func newStatus(ok bool, msg string) common.Status {
	return common.NewStatus(ok, msg, time.Now())
}

type last_status struct {
	status common.Status
	io     chan common.Status
}

func (ls *last_status) track() {
	for {
		select {
		case ls.status = <-ls.io:
		case ls.io <- ls.status:
		}
	}
}

type status_tracker struct {
	state map[int]*last_status
}

func NewStatusTracker(ports intslice) common.StatusTracker {
	st := new(status_tracker)
	st.state = make(map[int]*last_status)
	for _, port := range ports {
		ls := new(last_status)
		ls.io = make(chan common.Status)
		st.state[port] = ls
		go ls.track()
	}
	return st
}

func (st *status_tracker) Status(port int) (common.Status, error) {
	ls, ok := st.state[port]
	var outputStatus common.Status

	if ok {
		outputStatus = <-ls.io
	}

	if !ok || outputStatus == nil {
		return nil, errors.New("No status available")
	}

	return outputStatus, nil
}

func (st *status_tracker) MarkDown(port int, reason string) error {
	ls, ok := st.state[port]
	if !ok {
		return errors.New("Not Tracking port")
	}
	ls.io <- newStatus(false, reason)
	return nil
}

func (st *status_tracker) MarkUp(port int, reason string) error {
	ls, ok := st.state[port]
	if !ok {
		return errors.New("Not Tracking port")
	}
	ls.io <- newStatus(true, reason)
	return nil
}
