//go:generate ${GOBIN}/mockgen -destination api_mock.go -package=jumppod ${GO_MODULE}/pkg/service/jump/jumppod JumpPodManager,JumpPod
package jumppod

import (
	"context"

	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"

	jpent "github.com/tidbcloud/devops/entity/jump"
	"github.com/tidbcloud/devops/pkg/service/jump/jumppod/types"
)

// IsNotFound check whether the jump pod is not found.
func IsNotFound(err error) bool {
	return apierrors.IsNotFound(err)
}

type JumpPod interface {
	// Pod returns k8s pod of jump pod
	Pod() *corev1.Pod
	// Name returns the name of jump pod.
	Name() string
	// ID returns the id of jump pod.
	ID() types.ID
	// IsReady check if the jump pod is ready to use.
	IsReady(ctx context.Context) error
	// GenerateAccessToken generate a access token used to access the jump pod
	GenerateAccessToken(ctx context.Context, param *types.GenerateAccessTokenParam) (*types.Token, error)
	// PrepareJump make the jump pod ready to jump to the destination.
	PrepareJump(ctx context.Context, dest jpent.IDestination, param *types.PrepareJumpParam) (*types.JumpParam, error)
	// FinalizeJump clean up the jump pod after jump to the destination.
	FinalizeJump(ctx context.Context, destination jpent.IDestination, attr jpent.JumpAttributes) error
	// RefreshJump refresh the jump token.
	RefreshJump(ctx context.Context, dest jpent.IDestination, attr jpent.JumpAttributes, param *types.RefreshJumpParam) (*types.JumpParam, error)
}

type JumpPodManager interface {
	// Initialize all required resources
	Initialize(ctx context.Context) error
	// ListJumpPods list all existing jump pods.
	ListJumpPods(ctx context.Context) ([]JumpPod, error)
	// GetJumpPod get a jump pod.
	GetJumpPod(ctx context.Context, name string) (JumpPod, error)
	// SetUpJumpPod create a jump pod.
	SetUpJumpPod(ctx context.Context, name string) (JumpPod, error)
	// TearDownJumpPod delete a jump pod.
	TearDownJumpPod(ctx context.Context, name string) error
	// SupportedDestinations returns the supported destination names.
	//
	// If the names is nil, it means destinations are dynamic.
	SupportedDestinations(typ jpent.DestinationType) []string
}
