package util

import (
	"context"
	"fmt"

	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/client"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

// ReplayReader knows how to get a Cluster CR based on replay ID.
type ReplayReader interface {
	Get(ctx context.Context, cli client.Client, replayId string) (*cloudv1.Replay, error)
}

var _ ReplayReader = &LabelSelectorReplayReader{}

// LabelSelectorReplayReader get a Replay CR via LIST with label selectors.
type LabelSelectorReplayReader struct{}

func (r *LabelSelectorReplayReader) Get(ctx context.Context, cli client.Client, replayId string) (*cloudv1.Replay, error) {
	var list cloudv1.ReplayList
	if err := cli.List(ctx, &list, client.MatchingLabelsSelector{
		Selector: labels.Set{
			cloudv1.ReplayTagKey: replayId,
		}.AsSelector(),
	}); err != nil {
		return nil, fmt.Errorf("failed to list replays: %w", err)
	}

	if len(list.Items) == 0 {
		return nil, errors.NewNotFound(schema.GroupResource{Group: "cloud.pingcap.com", Resource: "replay"}, replayId)
	}

	if len(list.Items) > 1 {
		return nil, fmt.Errorf("found more than one replay with label %s=%s", cloudv1.ReplayTagKey, replayId)
	}

	return &list.Items[0], nil
}
