package reconciler

import (
	"github.com/tidbcloud/aws-shared-provider/pkg/tidbworker/resourcemanager/poolmanager/factory"
	rm "github.com/tidbcloud/aws-shared-provider/pkg/tidbworker/resourcemanager/types"
	providertypes "github.com/tidbcloud/aws-shared-provider/pkg/types"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/selection"
)

// invalidPool returns a selector that selects all workers with invalid pool.
func invalidPool(poolsConfig map[rm.WorkerPool]*rm.PoolConfig) (labels.Selector, error) {
	specifiedPools := make([]string, 0, len(poolsConfig))
	for pool := range poolsConfig {
		specifiedPools = append(specifiedPools, string(pool))
	}
	selector := labels.SelectorFromSet(factory.WorkerLabels())
	requirement, err := labels.NewRequirement(providertypes.WorkerPoolLabelKey, selection.NotIn, specifiedPools)
	if err != nil {
		return nil, err
	}
	selector = selector.Add(*requirement)
	return selector, nil
}

// outdatedRevision returns a selector that selects all workers in the pool with outdated revision.
func outdatedRevision(pool rm.WorkerPool, revision string) (labels.Selector, error) {
	selector := labels.SelectorFromSet(factory.WorkerLabels())
	reqPool, err := labels.NewRequirement(providertypes.WorkerPoolLabelKey, selection.Equals, []string{string(pool)})
	if err != nil {
		return nil, err
	}
	reqRevision, err := labels.NewRequirement(providertypes.RevisionLabelKey, selection.NotIn,
		[]string{revision})
	if err != nil {
		return nil, err
	}
	return selector.Add(*reqRevision, *reqPool), nil
}

// invalidIndex returns a selector that selects all workers with invalid index.
func invalidIndex(pool rm.WorkerPool, size int) (labels.Selector, error) {
	selector := labels.SelectorFromSet(factory.WorkerLabels())
	validWorkerNames := make([]string, size)
	for i := 0; i < size; i++ {
		validWorkerNames[i] = string(factory.WorkerHandle(pool, i))
	}
	reqPool, err := labels.NewRequirement(providertypes.WorkerPoolLabelKey, selection.Equals, []string{string(pool)})
	if err != nil {
		return nil, err
	}
	reqWorker, err := labels.NewRequirement(providertypes.WorkerLabelKey, selection.NotIn, validWorkerNames)
	if err != nil {
		return nil, err
	}
	return selector.Add(*reqPool, *reqWorker), nil
}
