package workload

import (
	"context"

	"github.com/robfig/cron"
	"github.com/tidbcloud/pov-service/internal/config"
	"github.com/tidbcloud/pov-service/internal/pkg/log"
	"github.com/tidbcloud/pov-service/internal/repo"
	"github.com/tidbcloud/pov-service/internal/service"
	scripttask "github.com/tidbcloud/pov-service/internal/service/workload/script_task"
	"go.uber.org/dig"
)

type ScriptRunnerParams struct {
	dig.In

	*config.Config
	log.Logger
	Svc     service.Workload
	DB      repo.ScriptExec
	AuditDB repo.AuditLog

	*cron.Cron
}

type ScriptRunnerResult struct {
	dig.Out

	service.Runnable `group:"runnable"`
}

type scriptRunner struct {
	scriptProcessor scripttask.ScriptExecProcessor
	cron            *cron.Cron
}

func NewScriptRunner(params ScriptRunnerParams) ScriptRunnerResult {
	execProcessor := scripttask.NewScriptExecProcessor(
		scripttask.ExecProcessorParams{
			Db:        params.DB,
			Svc:       params.Svc,
			AuditRepo: params.AuditDB,
		},
	)

	r := scriptRunner{
		cron:            params.Cron,
		scriptProcessor: execProcessor,
	}
	return ScriptRunnerResult{
		Runnable: r,
	}
}

func (r scriptRunner) Run(ctx context.Context) error {
	log.Log.Infof("Start script runner")

	pollFunc := func() {
		_, err, _ := singleflightGroup.Do("script-scheduler", func() (any, error) {
			err := r.sync(ctx)
			return nil, err
		})
		if err != nil {
			log.Log.Errorf(err, "sync failed")
		}
	}
	err := r.cron.AddFunc("@every 10s", pollFunc)
	return err
}

func (r scriptRunner) sync(ctx context.Context) error {
	return r.scriptProcessor.Process(ctx)
}
