package action

import (
	"fmt"

	"braces.dev/errtrace"
	"github.com/tidbcloud/fastflow/pkg/entity/run"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/encoding/protojson"

	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/serverlessglobal"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/constant"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

type DeleteServerlessClusterAction struct {
	serverlessCli serverlessglobal.ServerlessGlobal
}

func NewDeleteServerlessClusterAction(serverlessCli serverlessglobal.ServerlessGlobal) *DeleteServerlessClusterAction {
	return &DeleteServerlessClusterAction{
		serverlessCli: serverlessCli,
	}
}

func (c *DeleteServerlessClusterAction) Name() string {
	return constant.TaskServerlessGlobalDeleteCluster
}

func (c *DeleteServerlessClusterAction) Run(ctx run.ExecuteContext, params any) error {
	cctx, span := workflow.GenerateContext(ctx)
	defer span.End()

	tilog.Info(cctx, "delete serverless cluster action start")
	requestJson, ok := ctx.GetVar(constant.KeyRequest)
	if !ok {
		return fmt.Errorf("delete serverless request is not found")
	}

	var request globalserverlessv1.ServerlessServiceDeleteRequest
	if err := protojson.Unmarshal([]byte(requestJson), &request); err != nil {
		return fmt.Errorf("unmarshal delete serverless request failed: %w", err)
	}

	request.ValidateOnly = false
	_, err := c.serverlessCli.DeleteCluster(cctx, &request)
	if err != nil {
		if s, ok := status.FromError(err); ok {
			// skip if serverless cluster is not found
			if s.Code() == codes.Code(bizerr.ErrCodeRecordNotFound) {
				tilog.Warn(cctx, "serverless cluster is not found", zap.String("cluster_id", request.ClusterId))
				return nil
			}
		}
		return errtrace.Wrap(err)
	}

	tilog.Info(cctx, "delete serverless cluster action end")
	return nil
}
