package notification import ( "fmt" "log/slog" "prism/service/util" ) type NotificationSender interface { Send(mapping *Mapping, notif Notification) error } type Dispatcher struct { store *Store senders map[Channel]NotificationSender logger *slog.Logger } func NewDispatcher(store *Store, logger *slog.Logger) *Dispatcher { return &Dispatcher{ store: store, senders: make(map[Channel]NotificationSender), logger: logger, } } func (d *Dispatcher) RegisterSender(channel Channel, sender NotificationSender) { d.senders[channel] = sender } func (d *Dispatcher) HasSignal() bool { _, ok := d.senders[ChannelSignal] return ok } func (d *Dispatcher) HasTelegram() bool { _, ok := d.senders[ChannelTelegram] return ok } func (d *Dispatcher) GetAvailableChannels() []Channel { var channels []Channel if d.HasSignal() { channels = append(channels, ChannelSignal) } if d.HasTelegram() { channels = append(channels, ChannelTelegram) } channels = append(channels, ChannelWebPush) return channels } func (d *Dispatcher) IsValidChannel(channel Channel) bool { return channel.IsAvailable(d.HasSignal(), d.HasTelegram()) } func (d *Dispatcher) Send(appName string, notif Notification) error { mapping, err := d.store.GetApp(appName) if err != nil { return util.LogError(d.logger, "Failed to get app mapping", err, "app", appName) } if mapping == nil { d.logger.Info("Registering new app", "app", appName) availableChannels := d.GetAvailableChannels() if err := d.store.RegisterDefault(appName, availableChannels); err != nil { return util.LogError(d.logger, "Failed to register app", err, "app", appName) } mapping, err = d.store.GetApp(appName) if err != nil { return util.LogError(d.logger, "Failed to get mapping after registration", err, "app", appName) } if mapping == nil { return fmt.Errorf("mapping still nil after registration for app: %s", appName) } } sender, ok := d.senders[mapping.Channel] if !ok { d.logger.Error("No sender registered for channel", "channel", mapping.Channel) return fmt.Errorf("no sender for channel: %s", mapping.Channel) } return sender.Send(mapping, notif) }