package stario

import (
	"errors"
	"time"
)

var ERR_TIMEOUT = errors.New("TIME OUT")

func WaitUntilTimeout(tm time.Duration, fn func(chan struct{}) error) error {
	var err error
	finished := make(chan struct{})
	imout := make(chan struct{})
	go func() {
		err = fn(imout)
		finished <- struct{}{}
	}()
	select {
	case <-finished:
		return err
	case <-time.After(tm):
		close(imout)
		return ERR_TIMEOUT
	}
}

func WaitUntilFinished(fn func() error) <-chan error {
	finished := make(chan error)
	go func() {
		err := fn()
		finished <- err
	}()
	return finished
}

func WaitUntilTimeoutFinished(tm time.Duration, fn func(chan struct{}) error) <-chan error {
	var err error
	finished := make(chan struct{})
	result := make(chan error)
	imout := make(chan struct{})
	go func() {
		err = fn(imout)
		finished <- struct{}{}
	}()
	go func() {
		select {
		case <-finished:
			result <- err
		case <-time.After(tm):
			close(imout)
			result <- ERR_TIMEOUT
		}
	}()
	return result
}
