package tidbupgrader

import (
	"context"
	"testing"

	"github.com/go-logr/logr"
	. "github.com/onsi/gomega"
	"github.com/tidbcloud/aws-shared-provider/pkg/scheme"
	"github.com/tidbcloud/aws-shared-provider/pkg/tidbpool"
	"github.com/tidbcloud/aws-shared-provider/pkg/types"
	"github.com/tidbcloud/aws-shared-provider/pkg/utils/clientfake"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
	"sigs.k8s.io/controller-runtime/pkg/log"
)

func TestTidbUpgrader_handleOldAbnormal(t *testing.T) {
	tests := []struct {
		name            string
		tidbPool        *tidbpool.TidbPool
		abnormalPodList []corev1.Pod
		wantRemovePods  int
	}{
		{
			name: "remove one old revision tidb pod",
			tidbPool: &tidbpool.TidbPool{
				TidbPod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{
					GenerateName: types.TidbServerNamePrefix + "123-",
					Namespace:    "tidb-pool",
				}},
				Revision: "123",
				MinSize:  5,
				MaxSize:  6,
			},
			abnormalPodList: []corev1.Pod{
				{ObjectMeta: metav1.ObjectMeta{
					Name:      types.TidbServerNamePrefix + "123-pod1",
					Namespace: "tidb-pool",
				}},
				{ObjectMeta: metav1.ObjectMeta{
					Name:      types.TidbServerNamePrefix + "321-pod1",
					Namespace: "tidb-pool",
				}},
			},
			wantRemovePods: 1,
		},
	}
	for _, tt := range tests {
		g := NewGomegaWithT(t)
		t.Run(tt.name, func(t *testing.T) {
			builder := fake.NewClientBuilder().WithScheme(scheme.Scheme)
			for i := range tt.abnormalPodList {
				builder = builder.WithObjects(&tt.abnormalPodList[i])
			}
			tu := &TidbUpgrader{
				Logger:   logr.New(log.NullLogSink{}),
				client:   builder.Build(),
				pool:     &clientfake.FakeTidbPool{PoolNamespace: "tidb-pool", AbnormalPods: tt.abnormalPodList},
				tidbPool: tt.tidbPool,
			}
			tu.handleOldAbnormal()

			abnormalPodList := &corev1.PodList{}
			g.Expect(tu.client.List(context.Background(), abnormalPodList, client.InNamespace("tidb-pool"))).To(Succeed())
			g.Expect(len(tt.abnormalPodList) - len(abnormalPodList.Items)).To(Equal(tt.wantRemovePods))
		})
	}
}
