package update

import (
	"fmt"
	"strings"

	"github.com/tidbcloud/metrics-integration/global/internal/domain/entity"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/config"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/dataplane"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/di"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/workflow"
	helmpackage "github.com/tidbcloud/metrics-integration/global/pkg/helm/pipeline"

	"github.com/shiningrush/fastflow/pkg/entity/run"
	"gorm.io/gorm"
)

// Only used in pipeline runtime config refresh during cluster topology updates.

type PipelineRefreshRuntimeConfigAction struct{}

func (a *PipelineRefreshRuntimeConfigAction) Name() string {
	return "PipelineRefreshRuntimeConfigAction"
}

func (a *PipelineRefreshRuntimeConfigAction) Run(ctx run.ExecuteContext, params interface{}) error {
	id, err := workflow.GetUint64FromRunVar(ctx, "id")
	if err != nil {
		return fmt.Errorf("invalid id: %v", err)
	}

	pipelineMetaData := &entity.Integration{}
	if err := di.DiCall(func(db *gorm.DB) error {
		return db.First(pipelineMetaData, id).Error
	}); err != nil {
		return fmt.Errorf("failed to get pipeline from db: %w", err)
	}

	// helm deploy
	// get targetCluster
	targetCluster, err := helmpackage.GetTargetClusterByClusterID(uint64(pipelineMetaData.ClusterID))
	if err != nil {
		return fmt.Errorf("failed to get clusterinfo: %w", err)
	}

	if !strings.EqualFold(targetCluster.ServicePlan, "Dedicated") {
		return nil
	}

	if len(targetCluster.Components) == 0 {
		return nil
	}

	serverAddr := config.Global().RegionalExecutorConfig.GetPipelineDataplaneServerAddr(id, string(pipelineMetaData.CloudProviderType), pipelineMetaData.Region)
	if serverAddr != "" {
		if err := dataplane.RemoteRefreshDedicatedClusterCPUConfig(ctx.Context(), fmt.Sprintf("%d", id), serverAddr, targetCluster.Components); err != nil {
			return fmt.Errorf("failed to refresh remote dedicated cpu config: %w", err)
		}
	} else {
		restConfig, err := dataplane.GetRestConfig(pipelineMetaData.Region)
		if err != nil {
			return fmt.Errorf("failed to get rest config: %w", err)
		}

		if err := dataplane.RefreshDedicatedClusterCPUConfig(ctx.Context(), restConfig, fmt.Sprintf("%d", id), targetCluster.Components); err != nil {
			return fmt.Errorf("failed to refresh local dedicated cpu config: %w", err)
		}
	}
	return nil
}
