package gke

import (
	"context"

	gkev1beta1 "github.com/crossplane-contrib/provider-gcp/apis/container/v1beta1"
	"sigs.k8s.io/controller-runtime/pkg/client"

	"github.com/tidbcloud/eks-provider/api/v1alpha1"
	"github.com/tidbcloud/eks-provider/controllers/tiflow/task/cluster"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/k8s"
)

// NodeGroupGC cleanup all node groups which have different spec-code as the tiflow-executor or tiflow-master.
// during scale-up-down, it's responsible to clean up previous node group
// note: this task only works on CREATE phase, it does NOT clean up node group we're using.
type NodeGroupGC struct {
	cluster.NodeGroupGC
}

var _ cluster.GCInterface = (*NodeGroupGC)(nil)

func NewNodeGroupGC(ctx *cluster.BaseContext, objCond *v1alpha1.Conditions) *NodeGroupGC {
	n := &NodeGroupGC{}
	n.NodeGroupGC = cluster.NodeGroupGC{
		BaseContext: ctx,
		Conditions:  objCond,
		Collector:   n,
	}
	return n
}

func (t *NodeGroupGC) GC(ctx context.Context, selector *client.MatchingLabelsSelector) deploy.Result {
	if err := t.BaseContext.Local.DeleteAllOf(ctx, &gkev1beta1.NodePool{}, selector); err != nil {
		t.BaseContext.Logger.Info("label selector not ready")
		return t.Retry()
	}

	return deploy.Done()
}

func (t *NodeGroupGC) CheckGCResult(ctx context.Context, selector *client.MatchingLabelsSelector) deploy.Result {
	ngs := &gkev1beta1.NodePoolList{}
	ops := k8s.ListOpts[*gkev1beta1.NodePool]{
		ObjectList: ngs,
		Unpack:     func() []*gkev1beta1.NodePool { return k8s.MapPtr(ngs.Items) },
	}
	list, err := ops.ListFilterBy(ctx, t.BaseContext.Local,
		func(_ *gkev1beta1.NodePool) bool { return true }, selector)
	if client.IgnoreNotFound(err) != nil {
		t.BaseContext.Logger.Error(err, "query nodegroup occur error!")
		return t.Retry()
	}
	if len(list) != 0 {
		t.BaseContext.Logger.Info("nodegroup not deleted, remain!", "size", len(list))
		return t.Retry()
	}
	return deploy.Done()
}
