package schedule

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/pingcap/log"
	"go.uber.org/zap"
)

type DoUndo interface {
	Do() error
	Undo() error
}

func RunPeriodically(ctx context.Context, schedule string, duration time.Duration, p DoUndo, name string) error {
	scheduleD, errD := time.ParseDuration(strings.TrimSpace(strings.TrimPrefix(schedule, "@every")))
	if errD != nil {
		return errD
	}
	ticker := time.NewTicker(scheduleD)

	go func() {
		for {
			select {
			case <-ctx.Done():
				err := p.Undo()
				if err != nil {
					log.Warn(fmt.Sprintf("RunPeriodically.Undo for %s errored", name), zap.Error(err))
				}
				ticker.Stop()
				return
			case <-ticker.C:
				err1 := p.Do()
				if err1 != nil {
					log.Warn(fmt.Sprintf("RunPeriodically.Do for %s errored", name), zap.Error(err1))
				}
				select {
				case <-ctx.Done():
				case <-time.After(duration):
				}
				err2 := p.Undo()
				if err2 != nil {
					log.Warn(fmt.Sprintf("RunPeriodically.Undo for %s errored", name), zap.Error(err1))
				}
			}
		}
	}()

	return nil
}
