package experiment

import (
	"context"

	"github.com/tidbcloud/chaos-svc/idl/pbgen/proto/chaos"
	"github.com/tidbcloud/chaos-svc/pkg/domain/repo"
	"github.com/tidbcloud/chaos-svc/pkg/domain/service/workflow"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"github.com/tidbcloud/pkgv2/log"
)

type SyncWorkflowFromInfraSvc struct {
	trans                    db.TransProvider
	workflowRepo             repo.WorkflowRepo
	syncWorkflowFromInfraSvc workflow.SyncWorkflowFromInfraSvc
}

func NewSyncWorkflowFromInfraSvc(
	trans db.TransProvider,
	workflowRepo repo.WorkflowRepo,
	syncWorkflowFromInfraSvc workflow.SyncWorkflowFromInfraSvc,
) *SyncWorkflowFromInfraSvc {
	return &SyncWorkflowFromInfraSvc{
		trans:                    trans,
		workflowRepo:             workflowRepo,
		syncWorkflowFromInfraSvc: syncWorkflowFromInfraSvc,
	}
}

func (svc *SyncWorkflowFromInfraSvc) Execute(ctx context.Context) bizerr.BizError {
	logger := log.WithContextS(ctx)

	workflows, err := svc.workflowRepo.Query(ctx, repo.WorkflowFilter{
		Statuses: []chaos.ExperimentStatus{
			chaos.ExperimentStatus_EXPERIMENT_STATUS_RUNNING,
		},
	}, nil, nil)
	if err != nil {
		return err
	}

	succeedNum := 0
	for _, workflow := range workflows {
		if err := svc.trans.Transaction(ctx, func(ctx context.Context) error {
			return svc.syncWorkflowFromInfraSvc.Execute(ctx, workflow.ID)
		}); err != nil {
			logger.Warnf("sync chaos workflow from infra failed, projectID=%d, workflowID=%s: %s", workflow.ProjectID, workflow.ID, err)
			continue
		}

		succeedNum += 1
	}
	logger.Infof("sync chaos workflow done, succ: %d/%d", succeedNum, len(workflows))
	return nil
}
