diff --git a/sync/service/recur.go b/sync/service/recur.go new file mode 100644 index 0000000..f01de48 --- /dev/null +++ b/sync/service/recur.go @@ -0,0 +1,58 @@ +package main + +import ( + "log/slog" + "time" + + "go-mod.ewintr.nl/planner/item" +) + +type Recur struct { + repo Recurrer + logger *slog.Logger +} + +func NewRecur(repo Recurrer, interval time.Duration, logger *slog.Logger) *Recur { + r := &Recur{ + repo: repo, + logger: logger, + } + go r.run(interval) + + return r +} + +func (r *Recur) run(interval time.Duration) { + ticker := time.NewTicker(interval) + + for range ticker.C { + if err := r.recur(); err != nil { + r.logger.Error("could not recur", "error", err) + } + } +} + +func (r *Recur) recur() error { + items, err := r.repo.RecursBefore(time.Now()) + if err != nil { + return err + } + for _, i := range items { + if err := r.repo.RecursNext(i.ID, NewNext(i.Recurrer, i.RecurNext)); err != nil { + return err + } + } + + return nil +} + +func NewNext(r *item.Recur, old time.Time) time.Time { + day, _ := time.ParseDuration("1d") + test := old.Add(day) + for { + if r.On(test) || test.After(time.Date(2500, 1, 1, 0, 0, 0, 0, time.UTC)) { + return test + } + test.Add(day) + } +}