package hibernation

import (
	"context"
	"regexp"

	"github.com/crossplane-contrib/provider-aws/apis/eks/manualv1alpha1"
	"sigs.k8s.io/controller-runtime/pkg/client"

	gkev1beta1 "github.com/crossplane-contrib/provider-gcp/apis/container/v1beta1"

	"github.com/tidbcloud/eks-provider/controllers/tiflow/task"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/cloud/gcp"
	"github.com/tidbcloud/infra-provider/pkg/controllers/common"
	"github.com/tidbcloud/infra-provider/pkg/namer"
)

var (
	// InstanceGroup URL: https://www.googleapis.com/compute/{version}/projects/{projectName}/zones/{zone}/instanceGroupManagers/{instanceGroupName}
	instanceGroupUrlRe = regexp.MustCompile(`^https://www.googleapis.com/compute/(\S+)/projects/(\S+)/zones/(\S+)/instanceGroupManagers/(\S+)$`)
)

type HibernationHelper struct {
	GcpCli gcp.Client
}

func (h *HibernationHelper) OnlyMasterWorker(infraCli client.Client, network cloudv1.Network) bool {
	if network.Spec.Provider == cloudv1.ProviderTypeGKE {
		nps := &gkev1beta1.NodePoolList{}
		err := infraCli.List(context.TODO(), nps, client.MatchingLabels(map[string]string{
			"tidbcloud-namespace": network.Namespace,
			"tidbcloud-network":   network.Name,
			"tidbcloud-cluster":   common.ClustersShared,
		}))
		if err != nil {
			return false
		}
		tiflowNps := &gkev1beta1.NodePoolList{}
		err = infraCli.List(context.TODO(), tiflowNps, client.MatchingLabels(map[string]string{
			namer.LegacyNetworkNamespaceSelectorKey: network.Namespace,
			namer.LegacyNetworkSelectorKey:          network.Name,
			namer.TiflowNamespaceSelectorKey:        task.GetTiflowNamespace(&network),
		}))
		if err != nil {
			return false
		}
		nps.Items = append(nps.Items, tiflowNps.Items...)
		for _, np := range nps.Items {
			for _, url := range np.Status.AtProvider.InstanceGroupUrls {
				strs := instanceGroupUrlRe.FindStringSubmatch(url)
				if len(strs) != 5 {
					return false
				}
				size, err := h.GcpCli.GetInstanceGroupSize(context.TODO(), strs[2], strs[3], strs[4])
				if err != nil {
					return false
				}
				if size > int64(0) {
					return false
				}
			}
		}

		return true
	} else if network.Spec.Provider == cloudv1.ProviderTypeEKS {
		ng := new(manualv1alpha1.NodeGroupList)
		err := infraCli.List(context.TODO(), ng, client.MatchingLabels(map[string]string{
			"tidbcloud-namespace": network.Namespace,
			"tidbcloud-network":   network.Name,
		}))
		if err != nil {
			return false
		}
		if len(ng.Items) <= 1 {
			return true
		}
		return false
	}

	return false
}
