package server

import (
	"context"
	"fmt"

	"github.com/tidbcloud/cluster-service-ng/domain/workflow"
	"github.com/tidbcloud/cluster-service-ng/domain/workflow/dag"
	"github.com/tidbcloud/cluster-service-ng/pkg/runtime/actions"
	"github.com/tidbcloud/cluster-service-ng/pkg/utils"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func (s *serverImpl) ApplySemConfig(ctx context.Context, sharedPoolId string) error {
	if sharedPoolId == "" {
		return status.Errorf(codes.InvalidArgument, "shared pool id is empty")
	}

	// check if there is already a running apply sem config workflow
	dagIns, err := s.getRunningDagIns(ctx, []string{dag.PlanApplySemConfig}, []string{sharedPoolId}, nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to get running apply sem config dag instance, shared pool id: %s, err: %w", sharedPoolId, err)
	}
	if len(dagIns) > 0 {
		return status.Errorf(codes.AlreadyExists, "existing apply sem config workflow not finished, please try again later")
	}

	// verify shared pool exists
	sharedPool, err := s.sharedPoolRepo.Load(ctx, sharedPoolId, false)
	if err != nil {
		return fmt.Errorf("failed to load shared pool: %w", err)
	}
	if err := guardSharedPoolMutation(sharedPool, sharedPoolMutationBlockedWhilePaused); err != nil {
		return err
	}

	dagExecId := utils.GeneratedDagExecId(ctx, fmt.Sprintf("apply-sem-config-%s", sharedPoolId))
	err = s.dagExecutor.Submit(ctx,
		dag.PlanApplySemConfig,
		actions.ActionArgs{
			workflow.SharedPoolIdKey: actions.ActionArgString(sharedPoolId),
			utils.TraceIdKey:         utils.GetTraceId(ctx),
		},
		dagExecId)
	if err != nil {
		tilog.Error(ctx, "failed to submit apply sem config dag", zap.String("sharedPoolId", sharedPoolId), zap.Error(err))
		return fmt.Errorf("failed to submit apply sem config dag, shared pool id: %s, err: %w", sharedPoolId, err)
	}

	return nil
}
