package enable

import (
	"context"

	crrfRepo "github.com/tidbcloud/dataflow-service/app/repo/crrf"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/dataflow-service/app/workflow"
	"github.com/tidbcloud/dataflow-service/app/workflow/action"
	"go.uber.org/zap"
)

type markEnabledParams struct {
	ClusterID uint64 `json:"cluster_id"`
}

type markEnabledAction struct {
	crrfSettingRepo crrfRepo.CRRFSettingRepo
}

// NewMarkEnabledAction returns a Wrapper that transitions CRRFSetting status from enabling to enabled.
// This is the final action in the enable_crrf DAG.
func NewMarkEnabledAction(crrfSettingRepo crrfRepo.CRRFSettingRepo) *action.Wrapper {
	return action.MustNewActionWrapper(
		workflow.ActionCRRFMarkEnabled,
		&markEnabledAction{crrfSettingRepo: crrfSettingRepo},
	)
}

func (a *markEnabledAction) Params() interface{} {
	return &markEnabledParams{}
}

func (a *markEnabledAction) Run(ctx context.Context, logger *zap.Logger, params interface{}) error {
	p := params.(*markEnabledParams)

	setting, bizErr := a.crrfSettingRepo.GetByClusterID(ctx, p.ClusterID)
	if bizErr != nil {
		return bizErr
	}
	if setting.Status == entity.CRRFSettingStatusEnabled {
		logger.Info("crrf setting already enabled, idempotent skip")
		return nil
	}
	if setting.Status != entity.CRRFSettingStatusEnabling {
		logger.Warn("unexpected crrf setting status, skipping", zap.String("status", string(setting.Status)))
		return nil
	}

	setting.Status = entity.CRRFSettingStatusEnabled
	if saveErr := a.crrfSettingRepo.Save(ctx, setting); saveErr != nil {
		return saveErr
	}

	logger.Info("crrf setting marked as enabled", zap.Uint64("clusterID", p.ClusterID))
	return nil
}
