package handler

import (
	"sync"
	"context"
	"log"
)

// 자식들을 기다리는 context waiter
type Handler struct {
	errorChan chan error
	ctx       context.Context
	canceler  context.CancelFunc
	waiter    *sync.WaitGroup
}

func NewHandler(ctx context.Context) *Handler {
	ctx, canceler := context.WithCancel(ctx)
	return &Handler{
		ctx:       ctx,
		canceler:  canceler,
		waiter:    &sync.WaitGroup{},
		errorChan: make(chan error, 5),
	}
}

func (h *Handler) NotifyError(err error) { h.errorChan <- err }
func (h *Handler) Error() <-chan error   { return h.errorChan }
func (h *Handler) Done() <-chan struct{} { return h.ctx.Done() }
func (h *Handler) GracefulWait() {
	if h.ctx.Err() == nil {
		h.canceler()
	}

	h.waiter.Wait()
	close(h.errorChan)

	for remainError := range h.errorChan {
		log.Println("remain errors ", remainError)
	}
}

func (h *Handler) IncreaseWait() {
	h.waiter.Add(1)
}
func (h *Handler) DecreaseWait() {
	h.waiter.Done()
}
