package gatewaycontroller

import (
	"context"
	"strings"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	logf "sigs.k8s.io/controller-runtime/pkg/log"
	"sigs.k8s.io/controller-runtime/pkg/predicate"
)

// PodAnnotationReconciler add cluster-autoscaler annotations and zr labels to pods
type PodAnnotationReconciler struct {
	client.Client
	Scheme *runtime.Scheme
	Config *Config
}

func (r *PodAnnotationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	logger := logf.FromContext(ctx)

	var pod corev1.Pod
	if err := r.Get(ctx, req.NamespacedName, &pod); err != nil {
		logger.Error(err, "unable to fetch Pod")
		return ctrl.Result{}, client.IgnoreNotFound(err)
	}

	if pod.Annotations == nil {
		pod.Annotations = make(map[string]string)
	}

	value := "false"
	key := "cluster-autoscaler.kubernetes.io/safe-to-evict"
	if r.Config != nil && r.Config.CloudProvider == "alicloud" {
		key = "goatscaler.io/safe-to-evict"
	}
	if pod.Annotations[key] == value {
		return ctrl.Result{}, nil
	}

	pod.Annotations[key] = value

	if !strings.Contains(pod.Name, ingressClassPrivateLinkZR) {
		pod.Labels["zr-evicter.tidbcloud.com/ignored"] = "true"
	}

	if err := r.Update(ctx, &pod); err != nil {
		logger.Error(err, "unable to update Pod")
		return ctrl.Result{}, err
	}
	logger.Info("Added safe-to-evict annotation to Pod", "pod", pod.Name)

	return ctrl.Result{}, nil
}

func (r *PodAnnotationReconciler) SetupWithManager(mgr ctrl.Manager) error {
	NameFilter := func(object client.Object) bool {
		if object.GetNamespace() != r.Config.Namespace {
			return false
		}
		if !strings.HasPrefix(object.GetName(), "haproxy") {
			return false
		}
		return true
	}
	byNamespaceFuncs := predicate.NewPredicateFuncs(NameFilter)

	return ctrl.NewControllerManagedBy(mgr).For(&corev1.Pod{}).
		WithEventFilter(byNamespaceFuncs).
		Complete(r)
}
