package notification import ( // External werr "git.gibonuddevalla.se/go/wrappederror" // Standard "log/slog" "net/url" "slices" ) type Service interface { SetLogger(*slog.Logger) GetPrio() int GetType() string SetPrio(int) SetExists(bool) // Exists in database Exists() bool // Exists in database String() string Send(int, []byte) error Update(url.Values) error Updated() Service Commit() JSON() []byte } type Manager struct { services []Service logger *slog.Logger } func NewManager(logger *slog.Logger) (nm Manager) { nm.services = []Service{} nm.logger = logger return } func (nm *Manager) AddService(service Service) { service.SetExists(true) nm.services = append(nm.services, service) slices.SortFunc(nm.services, func(a, b Service) int { if a.GetPrio() < b.GetPrio() { return -1 } if a.GetPrio() > b.GetPrio() { return 1 } return 0 }) } func (nm *Manager) GetService(prio int) *Service { for _, svc := range nm.services { if svc.GetPrio() == prio { return &svc } } return nil } func (nm *Manager) RemoveService(prioToRemove int) { nm.services = slices.DeleteFunc(nm.services, func(svc Service) bool { return svc.GetPrio() == prioToRemove }) } func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (err error) { for i, service := range nm.services { nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio()) if err = service.Send(problemID, msg); err == nil { fn(&nm.services[i], nil) break } else { data := struct { ProblemID int Msg []byte }{ problemID, msg, } werr.Wrap(err).WithData(data).Log() fn(&nm.services[i], err) } } return } func (nm *Manager) Services() (services []Service) { return nm.services }