package resolver

import (
	"context"
	"sync"

	"jiraport/pkg/log"
	"jiraport/pkg/queue"
)

type EventHandler interface {
	Handle(context.Context, queue.Event)
}

type Resolver struct {
	queue  <-chan queue.Event
	router map[string]EventHandler
	wg     sync.WaitGroup
}

func New(queue <-chan queue.Event) (*Resolver, error) {
	return &Resolver{queue: queue,
		router: make(map[string]EventHandler)}, nil
}

// start event loop, always spawn new thread to handle a event
func (rs *Resolver) Run(ctx context.Context) {
	for {
		select {
		case ev := <-rs.queue:
			log.Debug("resolver receive", ev.Name)
			handler, ok := rs.router[ev.Name]
			if ok {
				rs.wg.Add(1)
				go func() {
					handler.Handle(ctx, ev)
					rs.wg.Done()
				}()
			} else {
				log.Error("msg", "no matched handler", "event", ev)
			}
		case <-ctx.Done():
			rs.wg.Wait()
			return
		}
	}
}

// register event handler with a corresponding event name
func (rs *Resolver) Register(evName string, handler EventHandler) {
	rs.router[evName] = handler
}
