package server

import (
	"context"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	apiv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"
)

// replayClusterProvider loads source audit log material, target endpoints, and resolves
// dataplane kubernetes info for a cluster participating in a replay.
type replayClusterProvider interface {
	GetClusterType() apiv1.Replay_ClusterType
	LoadSourceMaterial(ctx context.Context) (replaySourceMaterial, error)
	LoadTargetEndpoints(ctx context.Context) ([]string, error)
	ResolveDataplane(ctx context.Context) (replayDataplaneResolution, error)
}

// replayDataplaneResolution carries the resolved Kubernetes configuration for the replay dataplane.
type replayDataplaneResolution struct {
	kubernetes     cloudv1.Kubernetes
	kubeconfigData []byte
}

// newReplayClusterProvider constructs the appropriate provider for the given cluster ref.
func newReplayClusterProvider(
	rctx *replayContext,
	clusterRef *apiv1.Replay_ClusterRef,
) (replayClusterProvider, error) {
	if clusterRef == nil || clusterRef.ClusterId == "" {
		return nil, errReplayDataplaneMissingDataNode
	}
	switch clusterRef.ClusterType {
	case apiv1.Replay_CLUSTER_TYPE_DEDICATED:
		return newDedicatedReplayProvider(rctx, clusterRef), nil
	case apiv1.Replay_CLUSTER_TYPE_PREMIUM:
		return newPremiumReplayProvider(rctx, clusterRef), nil
	default:
		return nil, unsupportedReplayClusterType(clusterRef.ClusterType)
	}
}

// newReplayClusterProviderFn is the package-level factory used by replayContext.initProviders.
// It can be overridden in tests to inject stub providers.
var newReplayClusterProviderFn = newReplayClusterProvider
