package tidbreclaimer

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/aws-shared-provider/pkg/utils/kubeapi"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/utils/ptr"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
	tidbStatusTimeout = 5 * time.Second
)

type Response struct {
	State        string `json:"state"`
	KeyspaceName string `json:"keyspace_name"`
}

func (tr *TidbReclaimer) ReclaimPods(inactivePods []string, port int) int {
	podsReclaimed := 0
	orphanPods := tr.tManager.FilterOrphanPods(inactivePods)

	for _, podName := range orphanPods {
		rplog := tr.WithValues("pod name", podName)

		pod := &corev1.Pod{}
		namespacedName := client.ObjectKey{Name: podName, Namespace: tr.tidbPoolNamespace}
		if err := tr.client.Get(tr.ctx, namespacedName, pod); err != nil {
			rplog.Error(err, "get pod failed")
			continue
		}

		// ensure the pod is not activated before reclaiming
		if kubeapi.IsPodReady(pod) {
			ctx, cancel := context.WithTimeout(tr.ctx, tidbStatusTimeout)
			status, err := tr.tidbController.GetStatus(ctx, fmt.Sprintf("%s:%d", pod.Status.PodIP, port))
			cancel()
			if err != nil {
				rplog.Error(err, "get tidb status failed")
				continue
			}

			if !status.IsStandby() {
				rplog.Info("pod isn't standby, skip reclaiming")
				continue
			}
		}

		deleteOptions := &client.DeleteOptions{
			GracePeriodSeconds: ptr.To[int64](0),
		}
		if err := tr.client.Delete(tr.ctx, pod, deleteOptions); client.IgnoreNotFound(err) != nil {
			rplog.Error(err, "delete pod failed")
			continue // we can catch it in the next cycle
		}

		podsReclaimed += 1
		rplog.Info("[pod lifecycle] pod is reclaimed")
	}

	return podsReclaimed
}
