package cluster

import (
	"context"
	"fmt"
	"testing"
	"time"

	. "github.com/onsi/gomega"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
)

func TestPendingDelete(t *testing.T) {
	g := NewGomegaWithT(t)
	scheme := runtime.NewScheme()
	g.Expect(cloudv1.AddToScheme(scheme)).To(Succeed())

	// deleted cluster
	cluster := &cloudv1.Cluster{
		ObjectMeta: v1.ObjectMeta{
			Name:      "cluster",
			Namespace: "default",
		},
		Status: cloudv1.ClusterStatus{
			Phase: cloudv1.ClusterPhasePendingDelete,
		},
	}

	// running backup will removed when cluster deleted
	backup := &cloudv1.Backup{
		ObjectMeta: v1.ObjectMeta{
			Name:      "backup",
			Namespace: cluster.Namespace,
		},
		Status: cloudv1.BackupStatus{
			Phase: cloudv1.BackupRunning,
		},
	}

	// all restore will deleted
	restore := &cloudv1.Restore{
		ObjectMeta: v1.ObjectMeta{
			Name:      "restore",
			Namespace: cluster.Namespace,
		},
		Status: cloudv1.RestoreStatus{
			Phase: cloudv1.RestoreFailed,
		},
	}
	// all import will deleted
	ipt := &cloudv1.Import{
		ObjectMeta: v1.ObjectMeta{
			Name:      "restore",
			Namespace: cluster.Namespace,
		},
		Status: cloudv1.ImportStatus{
			Phase: cloudv1.ImportPrepare,
		},
	}

	r := newFakeReconcileContext(cluster, nil)
	g.Expect(r.InfraClient.Create(context.TODO(), backup)).To(Succeed())
	g.Expect(r.InfraClient.Create(context.TODO(), restore)).To(Succeed())
	g.Expect(r.InfraClient.Create(context.TODO(), ipt)).To(Succeed())

	g.Eventually(func() error {
		if err := r.pendingDeleteCluster(); err != nil {
			return err
		}

		if err := r.InfraClient.Get(r.ctx, types.NamespacedName{
			Namespace: cluster.Namespace,
			Name:      cluster.Name,
		}, cluster); err != nil {
			return err
		}
		if cluster.Status.Phase != cloudv1.ClusterPhaseDeleting {
			return fmt.Errorf("cluster phase is not deleting")
		}
		return nil
	}, 10*time.Second, 1*time.Second).Should(Succeed(), "backup import restore will clean up")
}
