package server import ( "errors" "fmt" "os" "git.ctrlz.es/mgdelacroix/birthdaybot/model" "git.ctrlz.es/mgdelacroix/birthdaybot/notification" "git.ctrlz.es/mgdelacroix/birthdaybot/parser" "github.com/charmbracelet/log" ) var ErrNoNotificationServices = errors.New("there are no notification services configured") type Server struct { Logger *log.Logger config *model.Config workers []*Worker birthdays []*model.Birthday notificationServices []notification.NotificationService } func createNotificationServices(logger *log.Logger, config *model.Config) ([]notification.NotificationService, error) { notificationServices := []notification.NotificationService{} if config.TelegramNotifications != nil { telegramNotificationService, err := notification.NewTelegramNotificationService(logger, config.TelegramNotifications) if err != nil { return nil, fmt.Errorf("cannot create telegram notification service: %w", err) } notificationServices = append(notificationServices, telegramNotificationService) } if len(notificationServices) == 0 { return nil, ErrNoNotificationServices } return notificationServices, nil } func New(config *model.Config) (*Server, error) { logger := log.New(os.Stderr) logger.Debug("parsing CSV file", "birthdayFile", config.BirthdayFile) birthdays, err := parser.ParseCSV(config.BirthdayFile) if err != nil { logger.Error("cannot parse CSV file", "birthdayFile", config.BirthdayFile, "error", err) return nil, fmt.Errorf("cannot parse CSV file %s: %w", config.BirthdayFile, err) } logger.Debug("creating notification services from config") notificationServices, err := createNotificationServices(logger, config) if err != nil { logger.Error("error creating notification services", "error", err) return nil, err } logger.Info("creating server") server := &Server{ Logger: logger, config: config, birthdays: birthdays, notificationServices: notificationServices, } server.workers = []*Worker{NewWorker(server)} return server, nil } func (s *Server) Start() { s.Logger.Info("starting server") for _, worker := range s.workers { worker.Start() } s.Logger.Info("server started", "workers", len(s.workers)) } func (s *Server) Stop() { s.Logger.Info("stopping server") for _, worker := range s.workers { worker.Stop() } s.Logger.Info("server stopped", "workers", len(s.workers)) } func (s *Server) Notify(birthday *model.Birthday) error { errs := []error{} for _, service := range s.notificationServices { err := service.Notify(birthday) if err != nil { errs = append(errs, err) } } if len(errs) == 0 { return nil } return errors.Join(errs...) } func (s *Server) Birthdays() []*model.Birthday { return s.birthdays }