package configchange

import (
	"context"
	"fmt"

	utilruntime "k8s.io/apimachinery/pkg/util/runtime"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

const (
	CCStepNameEnsureUpdateToTCMarkAllDone = "EnsureUpdateToTC/mark-all-done"
)

type ensureUpdateToTC struct {
}

func newEnsureUpdateToTCApplier() *ensureUpdateToTC {
	out := &ensureUpdateToTC{}
	return out
}

func (r *ensureUpdateToTC) InitSteps(ctx context.Context, cc *cloudv1.ConfigChange) {
	utilruntime.Must(cc.AddStep(ctx, cloudv1.CCStepUpdateCR2Cluster, cloudv1.CCStepStatusPending, ""))
	utilruntime.Must(cc.AddStep(ctx, cloudv1.CCStepUpdateCR2TC, cloudv1.CCStepStatusPending, ""))
	utilruntime.Must(cc.AddStep(ctx, CCStepNameEnsureUpdateToTCMarkAllDone, cloudv1.CCStepStatusPending, ""))
}

func (r *ensureUpdateToTC) RegisterStepAction(re *ConfigChangeReconciler) {
	re.RegisterAction(CCStepNameEnsureUpdateToTCMarkAllDone, r.markAllDone)
}

func (r *ensureUpdateToTC) markAllDone(ctx context.Context, rx *ReconcileContext) (err error) {
	cc := rx.ConfigChange
	for _, compType := range cc.Status.ChangedComponents {
		comp := cc.ReadOnlyComponentStatus(compType)
		comp.Done = true
		comp.Reason = fmt.Sprintf("skipped, because the strategy is %s.", cc.Spec.ChangeStrategy)
		if err := cc.UpdateComponentStatus(ctx, compType, &comp); err != nil {
			return fmt.Errorf("update component status: %w", err)
		}
	}

	cc.UpdateStep(ctx, CCStepNameEnsureUpdateToTCMarkAllDone, cloudv1.CCStepStatusCompleted, "mark all components done")
	return nil
}
