package common

import (
	"context"

	"github.com/google/uuid"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/nextgenglobal"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

// ResumeResourcePoolIdempotently submits a resume request and reconciles an
// ambiguous retry against the resource pool's latest lifecycle state.
func ResumeResourcePoolIdempotently(
	ctx context.Context,
	nextGenCli nextgenglobal.NextGenGlobal,
	resourcePoolID uint64,
) error {
	_, err := nextGenCli.ResumeResourcePool(ctx, &globalngv1.ResumeResourcePoolRequest{
		ResourcePoolId: resourcePoolID,
		OperationId:    uuid.NewString(),
	})
	if err == nil {
		return nil
	}
	if !isFailedPrecondition(err) {
		return err
	}

	profile, getErr := nextGenCli.GetResourcePool(ctx, &globalngv1.GetResourcePoolRequest{
		ResourcePoolId: resourcePoolID,
	})
	if getErr != nil || profile.GetResourcePool() == nil {
		return err
	}
	switch profile.GetResourcePool().GetLifecycleState() {
	case globalngv1.ResourcePool_RESUMING, globalngv1.ResourcePool_ACTIVE:
		return nil
	default:
		return err
	}
}

func isFailedPrecondition(err error) bool {
	if status.Code(err) == codes.FailedPrecondition {
		return true
	}
	_, ok := bizerr.AsCode(err, bizerr.ErrCode(codes.FailedPrecondition))
	return ok
}
